美文网首页
自己实现jQuery API

自己实现jQuery API

作者: 阿龙哟 | 来源:发表于2018-10-16 17:23 被阅读0次

    this 是call 的第一个参数!!!
    this是call的第一个参数!!!
    this是call的第一个参数!!!


    <!DOCTYPE html>
    <html>
    <head>
    <meta name="description" content="封装两个函数" />
      <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>
    

    封裝兩個函數:1.獲取相鄰元素,給偽數組添加元素
    1.0版,虽然可以实现,但是在全局中定义这些函数可能会覆盖别人定义的函数

     //获取所有相邻元素
    function getSiblings(node) {
        var allChildren = node.parentNode.children
        var siblings = {
          length: 0
        }
        for (let i = 0; i < allChildren.length; i++) {
          if (allChildren[i].id !== node.id) {
            siblings[siblings.length] = allChildren[i] //给伪数组添加元素
            siblings.length += 1
          }
        }
        return siblings
      }
    
      var classes = {
        a: true,
        b: false,
        c: true
      }
      
      
      //添加类名
      function addClass(classes,node) {
    
        for (let key in classes) {
          if (classes[key]) {
            node.classList.add(key)
          } else {
            node.classList.remove(key)
          }
        }
      }
    
    addClass.call(undefined,classes,item1)
    

    2.0版

    //获取所有相邻元素
    function getSiblings(node) {
       var allChildren = node.parentNode.children
       var siblings = {
         length: 0
       }
       for (let i = 0; i < allChildren.length; i++) {
         if (allChildren[i].id !== node.id) {
           siblings[siblings.length] = allChildren[i] //给伪数组添加元素
           siblings.length += 1
         }
       }
       return siblings
     }
    
     
     //添加类名
     function addClass(classes,node) {
       //代码优化准则,只要有相似代码,就一定可以优化
       for (let key in classes) {
         var value = classes[key]
         var method = value ? 'add':'remove'
         node.classList[method](key)
       }
     }
      
     window.along = {}
     along.getSiblings=getSiblings
     along.addClass = addClass
     console.log(along.getSiblings(item1))
     along.addClass({'a':true,'c':false},item1)
     
    //设计模式 命名空间
    

    定义一个名为along的对象空间,其中有两条函数属性,分别对应着这两个函数,使用的时候调用along里的函数,就可以避免覆盖别人函数的问题了,这种方法是一种设计模式名为命名空间

    但是还是会有点问题,每次使用都要前缀名


    3.0版
    能不能直接用item来调用这两个办法,所以想到在原型上添加这两个方法

     //获取所有相邻元素
    Node.prototype.getSiblings=function () {
        var allChildren = this.parentNode.children
        var siblings = {
          length: 0
        }
        for (let i = 0; i < allChildren.length; i++) {
          if (allChildren[i].id !== this.id) {
            siblings[siblings.length] = allChildren[i] //给伪数组添加元素
            siblings.length += 1
          }
        }
        return siblings
      }
      //添加类名
      Node.prototype.addClass=function(classes) {
        classes.forEach((value)=>this.classList.add(value))
      }
       
      console.log(item2.getSiblings())
    item4.addClass(['a','b'])
    

    4.0 版直接在原型上添加好像也有点问题,要是这个函数原来原型上就有了怎么办?所以从新构建一个Node2对象,,上面那种方法是通过this获取节点,这里我们直接传入一个node节点

    window.Node2 = function(node) {
      return {
        getSiblings: function() {
          var allChildren = node.parentNode.children
          var siblings = {
            length: 0
          }
          for (let i = 0; i < allChildren.length; i++) {
            if (allChildren[i].id !== node.id) {
              siblings[siblings.length] = allChildren[i] //给伪数组添加元素
              siblings.length += 1
            }
          }
          return siblings
        },
        addClass: function(classes) {
          classes.forEach((value) => node.classList.add(value))
        }
      }
    }
    
    var node2 = Node2(item3)
    console.log(node2.getSiblings(item2))
    node2.addClass(['a','b'])
    

    同时,把Node2改成jQuery,这个就是jQuery的模式了。给我旧的对象返回一个新的API,有新的方法


    5.0版 改进传入的参数,如果是Node节点,就直接使用,如果是个选择器,则找到相对应的节点

    window.jQuery = function(nodeOrSelector) {
      let node
      if(typeof nodeOrSelector === 'string'){
        node=document.querySelector(nodeOrSelector)
      }
      else{
        node = nodeOrSelector
      }
      
      return {
        getSiblings: function() {
          var allChildren = node.parentNode.children
          var siblings = {
            length: 0
          }
          for (let i = 0; i < allChildren.length; i++) {
            if (allChildren[i].id !== node.id) {
              siblings[siblings.length] = allChildren[i] //给伪数组添加元素
              siblings.length += 1
            }
          }
          return siblings
        },
        addClass: function(classes) {
          classes.forEach((value) => node.classList.add(value))
        }
      }
    }
    
    var node2 = jQuery('ul>li:nth-child(5)')
    console.log(node2.getSiblings())
    node2.addClass(['blue','a','b'])
    

    升级版JQuery函数

    window.jQuery = function(orderSelector) {
      let nodes = {}
      if (typeof orderSelector === 'string') {
        let temp = document.querySelectorAll(orderSelector)
        for (let i = 0; i < temp.length; i++) {
          nodes[i] = temp[i]
          nodes.length = temp.length
        }
      } else if (oederSelector instanceof Node) {
        nodes = {
          0: orderSelector,
          length: 1
        }
      }
    
      nodes.addClass = function(classes) {
        classes.forEach((value) => {
          for (let i = 0; i < nodes.length; i++) {
            nodes[i].classList.add(value)
          }
        })
      }
    
      nodes.text = function(text) {
        if (text === undefined) {
          let texts = []
          for (let i = 0; i < nodes.length; i++) {
            texts.push(nodes[i].textContent)
          }
          return texts
        } else {
          for (let i = 0; i < nodes.length; i++) {
            nodes[i].textContent = text;
          }
        }
      }
      return nodes
    }
    var node2 = jQuery('ul>li')
    node2.addClass(['red', 'blue'])
    console.log(node2.text())
    node2.text('tuesday')
    

    模拟jQuery,实现了选择器,实现了添加类名,读取文本设置文本这几个
    函数


    再加个缩写

    window.$ = jQuery
    var node2 = $('ul>li')
    

    Query 优点:
    1.兼容性很好
    2除了 DOM操作,还有动画,ajax
    3.jQuery 的功能更丰富

    相关文章

      网友评论

          本文标题:自己实现jQuery API

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