美文网首页我爱编程
jQuery的实质, 自己写一个jQuery

jQuery的实质, 自己写一个jQuery

作者: Apolo_Du | 来源:发表于2018-01-07 04:00 被阅读102次

jQuery 的实质:

  • 在了解了python的装饰器之后, 发现jQuery的本质就是一个装饰器, 只是它接受了不同的参数.
    • python装饰器接受一个函数, 在装饰器内部用一个函数(wrapper)将其包装, 并返回处理后的结果.
    • jQuery接受一个css选择器或dom对象作为参数, 返回一个包装后的对象(jQuery对象).

自定义DOM API

  • 实现一个获取兄弟元素的API
    • 通过定义 length属性, 让函数返回值可迭代, 成为一个类数组对象.
 function getSiblings(node){
    var allChildren = node.parentNode.children
    var array = {length:0}
    for (let i =0; i<allChildren.length; i++){
    if(allChildren[i] !== item3){
      array[array.length] = allChildren[i]
      array.length += 1
    }
  }
return array
}
  • 实现一个可批量增加/删除 类的API
    我们可以使用点记法 obj.attr 或者 obj[attr] 来调用一个对象的成员
function addClass(node, classes){
  for(let key in classes){
      var value = classes[key]
      var methodName = value?'add':'remove'
      node.classList[methodName](key)      
    }
}
  • 实现一个命名空间
    • JS中并不提供原生的命名空间支持
    • 我们可以创建一个简单对象字面量来打包所有的相关函数和变量。
      • 这个简单对象字面量模拟了命名空间的作用。
      • 避免覆盖全局变量
      • 为我们自定的API提供了一个统一的入口
window.myDom ={}
myDom.addClass = addClass
myDom.getSiblings = getSiblings
  • 让一个dom对象具有我们定义的API

    • 方法1:
      • 扩展 Node 接口, 在 Node.prototype上加函数.
      • 这个方法是不好的
  • 方法2:

    • 使用一个wrapper函数来包装这个对象并返回它, jQuery就是用这种的方式实现的
      • 接收一个dom对象, 返回一个新的jQuery对象.
      • jQuery 还能够区分传入的是字符串或是node节点
window.Node2 = function(nodeOrSelector) {
  let node
  if (typeof nodeOrSelector === 'string') {
    node = document.querySelector(nodeOrSelector)
  } else {
    node = nodeOrSelector
  }
  return {
    getSiblings: function() {
      var allChildren = node.parentNode.children
      var array = {
        length: 0
      }
      for (let i = 0; i < allChildren.length; i++) {
        if (allChildren[i] !== item3) {
          array[array.length] = allChildren[i]
          array.length += 1
        }
      }
      return array
    },
    addClass: function(classes) {
      for (let key in classes) {
        var value = classes[key]
        var methodName = value ? 'add' : 'remove'
        node.classList[methodName](key)
      }
    }
  }
}
  • 实现一个jQuery选择器
    • 我们要实现类似jQuery的功能, 每次都要能够获得一个jQuery对象这样的类数组对象.
      • 如果参数是一个字符串, 我们就通过 querySelectorAll 获取一个类数组对象
        • 迭代获得的对象, 将它的每一个元素放到新的对象中.
        • 要保证自定义的类数组对象有index下标和length属性. 这样它才是可迭代的
    • 如果参数是一个节点, 我们同样它放到一个具有 index 和 length的自定义类数组对象中.
window.jQuery = function(nodeOrSelector) {
  let nodes = {}
  if (typeof nodeOrSelector === 'string') {
    let temp = document.querySelectorAll(nodeOrSelector)
      //我们不要nodeList, 要一个自定的类数组元素
    for (let i = 0; i < temp.length; i++) {
      nodes[i] = temp[i]
    }
    nodes.length = temp.length
  } else if (nodeOrSelector instanceof Node) {
    nodes = {
      0: nodeOrSelector,
      length: 1
    }
  }
  • 对选择器对象设置 getText 和 setText 方法
    • getText方法要返回一个可迭代对象.
      • 其中每个元素存储一个选择器元素的 textContent值
    • setText 方法要对选择器进行统一设置
      • 对选择器的内一个元素的 textContent 进行设置.
  nodes.getText = function() {
    let text = []
    for (let i = 0; i < nodes.length; i++) {
      text.push(nodes[i].textContent)
    }
    return text
  }

  nodes.setText = function(text) {
    for (let i = 0; i < nodes.length; i++) {
      nodes[i].textContent = text
    }
    return nodes
  }
  • jQuery 中的 getText 和 setText 方法
    • 在jQuery中, 两种方法被合并了, 通过判断是否有传参数, 来执行不同的代码语句
 nodes.text = function(text) {
    if (text === undefined) {
      let text = []
      for (let i = 0; i < nodes.length; i++) {
        text.push(nodes[i].textContent)
      }
      return text
    } else {
      for (let i = 0; i < nodes.length; i++) {
        nodes[i].textContent = text
      }
      return nodes
    }
  }
  • 这其实类似python中的 @property 和 @attr.setter, 为getter方法和setter方法 提供了一个统一的接口

    • @property装饰器
  • nodes.text 函数和闭包

    • nodes.text 函数内部没有声明 nodes变量, 而是引用了函数外部的变量, nodes.text 函数和 nodes变量就构成了一个闭包.
  • 自定义jQuery的完整代码:

window.jQuery = function(nodeOrSelector) {
  let nodes = {}
  if (typeof nodeOrSelector === 'string') {
    let temp = document.querySelectorAll(nodeOrSelector)
      //我们不要nodeList, 要一个自定的类数组元素
    for (let i = 0; i < temp.length; i++) {
      nodes[i] = temp[i]
    }
    nodes.length = temp.length
  } else if (nodeOrSelector instanceof Node) {
    nodes = {
      0: nodeOrSelector,
      length: 1
    }
  }

  nodes.addClass = function(classes) {
    for (let key in classes) {
      var value = classes[key]
      var methodName = value ? 'add' : 'remove'
      for (let i = 0; i < nodes.length; i++) {
        nodes[i].classList[methodName](key)
      }
    }
  }

  nodes.text = function(text) {
    if (text === undefined) {
      let text = []
      for (let i = 0; i < nodes.length; i++) {
        text.push(nodes[i].textContent)
      }
      return text
    } else {
      for (let i = 0; i < nodes.length; i++) {
        nodes[i].textContent = text
      }
      return nodes
    }
  }
  return nodes
}

相关文章

  • jQuery的实质, 自己写一个jQuery

    jQuery 的实质: 在了解了python的装饰器之后, 发现jQuery的本质就是一个装饰器, 只是它接受了不...

  • 一个jQuery的使用实例

    jQuery的作者是John Resig jQuery官网 jQuery实质上是一个函数,它接收一个节点或者选择器...

  • jQuery

    1. jQuery是什么? jQuery 是一个 JavaScript 库。 jQuery 是一个“写的更少,但做...

  • 00-jQuery初识

    什么是jQuery jQuery是一个JavaScript库 jQuery可以简化原生JS的操作 对比原生JS,写...

  • 自定义封装一个简易jQuery

    jQuery实质为构造函数,这个构造函数接受一个参数,jQuery内部通过这个参数利用原生的API找到相对应的DO...

  • 前端学习笔记之jQuery

    什么是 jQuery ?jQuery是一个JavaScript函数库。 jQuery是一个轻量级的"写的少,做的多...

  • jquery内部实现原理

    含摘录,非原创 jQuery实质上是一个构造函数,该构造函数接受一个参数,jQuery通过这个参数利用原生API找...

  • 七、jQuery基础

    一、jQuery介绍 jQuery是一个JavaScript函数库。jQuery是一个轻量级的"写的少,做的多"的...

  • jquery初识

    什么是jquery: jQuery是一个javascript的函数库 jQuery是一个轻量级的"写的少,做的多"...

  • 模拟 jQuery API的实现

    jQuery 是什么? jQuery实质上是一个构造函数,接受一个参数,这个参数可能是节点,然后返回一个方法对象去...

网友评论

    本文标题:jQuery的实质, 自己写一个jQuery

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