Contents
  1. 1. 有些时候,需要我们用DOM的API封装一些函数
  2. 2. 放到命名空间中
  3. 3. 放到Node的prototype中
  4. 4. 写一个jQuery构造函数
  5. 5. 总结

jQuery的重要性不必多讲,对于刚接触js,特别是刚学习完DOM模型的人需要了解的是为什么要学习jQuery呢,jQuery的本质是什么,它与DOM模型的关系是什么?
自己动手封装一个jQuery构造函数可以解决这些问题。

有些时候,需要我们用DOM的API封装一些函数

举一个最简单的例子,我们现在想封装这样一个函数,可以接受一个节点或者一组节点,或者一个选择器作为参数,并且给它加上一个class。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function addClass(nodesOrSelector,className){
if (typeof nodesOrSelector === "string") {
//如果参数是字符串的话,代表是一个选择器
var nodes = document.querySelectorAll(nodesOrSelector)
for (let i = 0; i < nodesOrSelector.length; i++) {
nodes[i].classList.add(className)
}
} else if (nodesOrSelector instanceof Node) {
//如果参数是一个node节点
nodesOrSelector.classList.add(className)
} else if (nodesOrSelector instanceof NodeList || nodesOrSelector instanceof HTMLAllCollection) {
//如果参数是一个节点集合,nodeList或HTMLCollection
for (let i = 0; i < nodesOrSelector.length; i++) {
nodesOrSelector[i].classList.add(className)
}
}
}

放到命名空间中

封装完之后我们决定优化一下,这是我们创造的工具呀,放在全局作用域里面可不好,为什么不放到我们的命名空间里面呢

1
2
window.qikke = {}
qikke.addClass = function(){...}

放到Node的prototype中

放到命名空间之后发现调用的时候有一点奇怪

1
qikke.addClass('ul > li','red')

我们想要的效果是这样的

1
xxx.addClass('red')

所以我们大胆的吧addClass这个函数放到了Node.prototype中

1
Node.prototype.addClass = function(){...}

于是一个接一个的工具函数被放到了Node的原型中。。。时不时的还会被覆盖掉几个。。。

写一个jQuery构造函数

所以我们下决心要自己写一个构造函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
window.jQuery = function (nodesOrSelector) {
var nodes = {}
if (typeof nodesOrSelector === "string") {
//如果参数是字符串的话,代表是一个选择器
//querySelectorAll返回一个nodeList 会从nodeList继承很多方法,过滤掉。
var temp = document.querySelectorAll(nodesOrSelector)
for (let i = 0; i < temp.length; i++) {
nodes[i] = temp[i]
}
nodes['length'] = temp.length
} else if (nodesOrSelector instanceof Node) {
//参数是一个node节点,把它构造成一个伪数组
nodes = {
0: nodesOrSelector,
length: 1
}
} else if (nodesOrSelector instanceof NodeList || nodesOrSelector instanceof HTMLAllCollection) {
//参数是一个节点集合,nodeList或HTMLCollection
for (let i = 0; i < nodesOrSelector.length; i++) {
nodes[i] = nodesOrSelector[i]
}
nodes['length'] = nodesOrSelector.length
}

//给nodes对象增加addClass方法
nodes.addClass = function(className){
//为nodes中的节点增加一个class
for(let i = 0; i < nodes.length; i++){
nodes[i].classList.add(className)
}
}

//返回构造好的jQuery对象
return nodes
}

var $div = jQuery('li')
$div.addClass('red')

总结

  • jQuery是一个构造函数,它可以包装普通的DOM对象,然后获得jQuery.prototype中的方法。
  • 而包装后的对象$div失去了与Node对象的联系,所以不能调用Node中的方法了。
Contents
  1. 1. 有些时候,需要我们用DOM的API封装一些函数
  2. 2. 放到命名空间中
  3. 3. 放到Node的prototype中
  4. 4. 写一个jQuery构造函数
  5. 5. 总结