29(M)-jQuery

2019-05-21  本文已影响0人  ChenMurphy

需求:造一个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
上一篇下一篇

猜你喜欢

热点阅读