美文网首页
29(M)-jQuery

29(M)-jQuery

作者: ChenMurphy | 来源:发表于2019-05-21 10:26 被阅读0次

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

    相关文章

      网友评论

          本文标题:29(M)-jQuery

          本文链接:https://www.haomeiwen.com/subject/gcklzqtx.html