工作生活

一个简单的jQuery!

2019-06-30  本文已影响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

上一篇 下一篇

猜你喜欢

热点阅读