美文网首页工作生活
一个简单的jQuery!

一个简单的jQuery!

作者: 饥人谷_丁健 | 来源:发表于2019-06-30 10:03 被阅读0次

    假设需要实现以下的需求

    window.jQuery = ???
    window.$ = jQuery
    
    var $div = $('div')
    $div.addClass('red')     // 可将所有 div 的 class 添加一个 red
    $div.setText('hi')       // 可将所有 div 的 textContent 变为 hi
    

    封装两个函数

    1.给某个节点添加类名

    function addClass(node,classes){}
    

    给节点 nodeX添加类名为redaddClass(nodeX, 'red')

    2.给某个节点设置文本内容

    function setText(node, text) { 
        node.textContent = text
    }
    

    给节点 nodeX设置文本内容为hisetText(nodeX, 'hi')

    命名空间。

    “命名空间”是一种设计模式,也就是这个函数名字只属于这个空间。相当于在函数名前面加了个前缀,用于标识该名字的所属空间。它们就不会与已有的相同标识符发生冲突。例:给上述两个函数命名为djdom

    window.djdom = {}
    djdom.addClass = addClass
    djdom.setText = setText
    
    //调用函数
    djdom.addClass(nodex, 'red')
    djdom.setText(nodex, 'hi')
    

    改写为 Node.prototype

    扩展 Node 接口,直接在Node.prototype上加函数

    Node.prototype.addClass = function(classes) { 
        this.classList.add(classes)
    }
    Node.prototype.setText = function(text) { 
        this.textContent = text
    }
    // 调用函数
    nodeX.addClass.call(nodeX, 'red') // 等价于 nodeX.addClass('red')
    nodeX.setText.call(nodeX, 'hi')  // 等价于 nodeX.getSiblings('hi')
    

    注意:nodeX.function.call(nodeX)为显示执行this
    nodeX.function()为隐式执行this
    新手最好用call() 调用函数,可以更好的对 this 的理解。thiscall的第一个参数。

    加深对于thiscall的第一个参数。
    的理解

    改写为 Node2

    改写为 Node.prototype这种方法,虽然定义函数方便,但确有很大的弊端,不同的人定义的函数会相互覆盖,比较杂乱,因此我们可以重写一个新的接口 Node2,再用它新提供的API 去操控节点。

    winddow.node2 = function(node){
      return{
      addClass:function(node,classes){
       node.addClass.add(classes) 
     }
     setText:function(node,text){
       node.textContent = text
     }
      }
    }
    //调用函数
    var node2 = Node2(nodex)
    node2.addClass('red')
    node2.setText('hi')
    

    改名为 jQuery

    winddow.jQuery = function(node){
      return{
      addClass:function(node,classes){
       node.addClass.add(classes) 
     }
     setText:function(node,text){
       node.textContent = text
     }
      }
    }
    //调用函数
    var node2 = jQuery(nodex)
    node2.addClass('red')
    node2.setText('hi')
    

    jQuery 其实相当于一个构造函数,它接受参数,然后返回一个新的对象,并调用新对象的 API 去操作接受的元素。

    jQuery 接受的参数不仅可以是节点,还可以是字符串:

    window.jQuery = function(nodeOrSelector){
      let node
      if(typeof nodeOrSelector === 'string'){ // 判断参数类型
        node = document.querySelector(nodeOrSelector) // 根据参数找对应节点
      }else{
        node = nodeOrSelector // 直接将字符串地址赋值给 node
      }
      return {
       addClass:function(node,classes){
       node.addClass.add(classes) 
     }
     setText:function(node,text){
       node.textContent = text
     }
      }
    }
    // 调用
    var node2 = jQuery ('#xxx') // 获取页面中 id 为 xxx 的元素
    node2.addClass({'red')
    node2.setText('hi')
    

    获取多个API:

    // 接受一个 Node 或选择器
    window.jQuery = function(nodeOrSelector) {
        // 封装成一个伪数组
        let nodes = {}
        if (typeof nodeOrSelector === 'string') {
          let temp = document.querySelectorAll(nodeOrSelector) // 伪数组
          for (let i = 0; i < temp.length; i++) {
            nodes[i] = temp[i]
          }
          nodes.length = temp.length
        } else if (nodeSelector instanceof Node) {
          nodes = {
            0: nodeOrSelector,
            length: 1
          }
        }
        // API
        nodes.addClass = function(classes) { 
          for (let i = 0; i < nodes.length; i++) {
            nodes[i].classList.add(classes)
          }
        }
        // API 
        nodes.setText = function(text) { 
          for (let i=0; i<nodes.length; i++) {
            nodes[i].textContent = text
          }
        }
        // 返回伪数组 nodes
        return nodes
    }
    // 调用
    var nodes = jQuery('li')  // 页面中的 li 标签
    nodes.addClass('red')
    nodes.setText('hi')
    

    模拟jQuery实现API,用alias $

    window.jQuery = function(nodeOrSeletor){
      let nodes ={}
      if(typeof nodeOrSeletor === 'string'){
        let temp = document.querySelectorAll(nodeOrSeletor)
        for(let i=0;i<temp.length;i++){
          nodes[i] = temp[i]
        }
        nodes.length = temp.length
      }else if(nodeOrSeletor instanceof Node){
          nodes = {0: nodeOrSeletor,length: 1}
      }
      
      nodes.addClass = function(classes){
        classes.forEach((value) => {
          for(let i=0;i<nodes.length;i++){
            nodes[i].classList.add(value)
          }
        })
      }
      
      nodes.setText = function(text){
        for(let i=0;i<nodes.length;i++){
          nodes[i].textContent = text
        }
      }
      
      return nodes
    }
    window.$ = jQuery
    
    var $div = $('div')
    $div.addClass(['red']) // 可将所有 div 的 class 添加一个 red
    $div.setText('你好') // 可将所有 div 的 textContent 变为 hi
    
    window.$ = jQuery
    

    注意: $表示这是对象是以jQuery构造出来的,表示它是jQuery 的对象,避免与DOM 对象混淆而用错方法。

    jQuery的练习题

    <ul>
        <li></li>
        <li></li>
    </ul>
    

    请写出$('li')的结构。

    答案:$('li')是一个对象,它自身的keyxxx,它的原型(共享属性)为 xxx.prototypexxx.prototypekeyxxxxxxxxx

    <div id=x></div>
    
    var div = document.getElementById('x')
    var $div = $('#x')
    

    请说出 div$div的联系和区别。

    答案:联系:
    都是通过id选择器得到相应的node节点
    可以相互转换
    1、把div变成$div:$div = $('div')
    只需要用$()dom对象包装起来,就能获得一个jQuery对象了
    2、把$div 变成div有以下两种方法:
    方法1.div= $div[0] //通过[index]来得到相应的dom对象
    方法2.div= $div.get(0) //jQuery提供的get(index)方法来得到相应的dom对象
    区别:
    divDOM对象,适用于DOM提供的API
    $divjQuery对象,适用于jQuery提供的API

    相关文章

      网友评论

        本文标题:一个简单的jQuery!

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