需求:造一个API可以获取所有兄弟姐妹节点
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<ul>
<li id="item1">选项1</li>
<li id="item2">选项2</li>
<li id="item3">选项3</li>
<li id="item4">选项4</li>
<li id="item5">选项5</li>
</ul>
</body>
</html>
//第一步声明一个变量把所有children收集起来
var allChildren = item3.parentNode.children
//然后二话不说遍历它
for (let i =0; i < allChildren.length; i++){}
//1.声明一个伪数组。2.遍历。3.判断是否等于自己。4.放入伪数组。5.length+1
var array = {
length: 0
}
for(let i = 0; i < allChildren.length; i++){
if (allChildren[i] !==item3){
array[array.length] = allChildren[i]
array.length +=1
}
}
//然后封装个函数
function getSiblings(nodes) {
var allChildren = nodes.parentNode.children
var array = {
length: 0
}
for (let i = 0; i < allChildren.length; i++) {
if (allChildren[i] !== nodes) {
array[array.length] = allChildren[i]
array.length += 1
}
}
return array
}
console.log(getSiblings(item3))
//如果要给item3加三个class
item3.classList.add('a')
item3.classList.add('b')
item3.classList.add('c')
//这肯定不行一看就很蠢,重新申明一个数组,然后遍历这个数组
var classes = ['a','b','c']
classes.forEach((value) =>item3.classList.add(value))
//再进化一下,把classes做成可以add也可以remove,但是这时候数组就不够用了,要用哈希了也就是对象嘛。
//另外如果用了哈希就不能用forEach了要用for(let key in classes)
var classes = {'a':true,'b':false,'c':true}
for (let key in classes){
if(key === true){
item3.classList.add(key)
}else{
item3.classList.remove(key)
}
}
//封装成函数,我要对谁添加哪些class?所以需要两个参数
function addClasses(nodes, classes) {
for (let key in classes) {
if (classes[key]) {
nodes.classList.add(key)
} else {
nodes.classList.remove(key)
}
}
}
addClasses(item3, {'a': true,'b': true,'c': false})
console.log(item3)
//优化一下代码(出现类似代码就有优化的可能)
//就add和remove不同,而判断有个简化的写法。适用于判断后运行结果比较简单的情况
function addClasses(nodes,classes) {
for (let key in classes) {
var methodName = classes[key] ? 'add' : 'remove'
item3.classList[methodName](key)
}
}
addClasses(item3,{'a': true,'b': true,'c': false})
console.log(item3)
//为了演示方便还是把addClass写得简单点
function addClasses(nodes,classes) {
classes.forEach(value =>nodes.classList.add(value))
}
//防止自创API覆盖其他变量
window.cyp ={}
cyp.getSiblings=function (nodes) {
var allChildren = nodes.parentNode.children
var array = {
length: 0
}
for (let i = 0; i < allChildren.length; i++) {
if (allChildren[i] !== nodes) {
array[array.length] = allChildren[i]
array.length += 1
}
}
return array
}
cyp.addClasses=function (nodes,classes) {
classes.forEach(value =>nodes.classList.add(value))
}
cyp.addClasses(item3,['a','b','c'])
console.log(item3)
//这是种方法声明一个cyp对象,对象里面放着函数,再试试另外一种方法。
//另外一种方法是声明一个函数,这个函数返回一个对象,对象里面放着函数。
window.cyp = function(node) {
return {
getSiblings: function(node) {
var allChildren = node.parentNode.children
var array = {
length: 0
}
for (let i = 0; i < allChildren.length; i++) {
if (allChildren[i] !== node) {
array[array.length] = allChildren[i]
array.length += 1
}
}
return array
},
addClasses: function(classes) {
classes.forEach(value => node.classList.add(value))
}
}
}
var cyp2 = cyp(item3)
cyp2.addClasses(['a', 'b','c'])
console.log(item3)
在对比一下这两种用法:
1.cyp.addClasses(item3,['a','b','c'])
2.var cyp2 = cyp(item3)
cyp2.addClasses(['a', 'b','c'])
所以如果我要对item1~100进行操作,第一种方法写100行代码,第二种写200行代码。第一种代码少!
如果我100个API都对item3进行操作。那第一种还是100行代码,第二种101行。第二种代码少!
把cyp换成jQuery就是jQuery了
//jQuery要比这个还厉害点,这里只能传入节点。jQuery可以传入选择器,所以再把代码升级一下
window.jQuery = function(nodeOrSelector) {
let node
if (typeof nodeOrSelector === "string") {
node = document.querySelector(nodeOrSelector)
} else {
node = nodeOrSelector
}
return {
getSiblings: function(node) {
var allChildren = node.parentNode.children
var array = {
length: 0
}
for (let i = 0; i < allChildren.length; i++) {
if (allChildren[i] !== node) {
array[array.length] = allChildren[i]
array.length += 1
}
}
return array
},
addClasses: function(classes) {
classes.forEach(value => node.classList.add(value))
}
}
}
var cyp2 = jQuery('#item3')
cyp2.addClasses(['a', 'b'])
console.log(item3)
//可以用选择器意味着除了id还能用节点如'ul > li:nth-child(3)'
var cyp2 = jQuery('ul > li:nth-child(3)')
现在我又想升级一下,要操作多个节点,给ul下面的所有li都加class,这在css中很常用所以这里必须也得有这个API。上面是判断传入的是string还是node,如果是string的话就根据string拿到node,下面是判断如果是string就收集所有的node放到一个伪数组。如果是node也放到一个伪数组。所以最终都是node的伪数组,里面可能是一个或者多个node。
window.jQuery = function(nodeOrSelector) {
let nodes = {}
if (typeof nodeOrSelector === "string") {
nodes = document.querySelectorAll(nodeOrSelector)
} else if (nodeOrSelector instanceof Node) {//这边要if里面写判断了,所以不能直接else要else if
node = {
0: nodeOrSelector,
length: 0
}
}
nodes.getSiblings = function() {
var allChildren = node.parentNode.children
var array = {
length: 0
}
for (let i = 0; i < allChildren.length; i++) {
if (allChildren[i] !== node) {
array[array.length] = allChildren[i]
array.length += 1
}
}
return array
}
nodes.addClasses = function(classes) {
classes.forEach(value => {
for (let i = 0; i < nodes.length; i++) {
nodes[i].classList.add(value)
}
})
}
return nodes
}
var cyp2 = jQuery('ul > li')
cyp2.addClasses(['a', 'b'])
console.log(item3)
再造一个获取文本API和改变文本API
nodes.getText = function() {
var texts = []
for (let i = 0; i < nodes.length; i++) {
// texts[i] = nodes[i].textContent
texts.push(nodes[i].textContent)
}
return texts
}
nodes.setText = function(text) {
for (let i = 0; i < nodes.length; i++) {
nodes[i].textContent = text
}
}
另外jQuery把getText和setText合并了。判断如果参入参数了,那么就是修改text如果没有传入就是获取text
nodes.text = function(text) {
if (text === undefined) {
var texts = []
for (let i = 0; i < nodes.length; i++) {
// texts[i] = nodes[i].textContent
texts.push(nodes[i].textContent)
}
return texts
} else {
for (let i = 0; i < nodes.length; i++) {
nodes[i].textContent = text
}
}
}
//undefined 和布尔以前判断用了true还是false这里用undefined
网友评论