需求
在不使用jQuery函数库的情况下自制一个与jQuery类似的API
首先,确认以下两个需求:1
2
3var $div = $('div')
$div.addClass('red') // 可将所有 div 的 class 添加一个 red
$div.setText('hi') // 可将所有 div 的 textContent 变为 hi
创建
先创建一个新的window对象jQuery,它是一个函数,并返回带有参数新的对象1
2
3
4
5window.jQuery=function(node){
return{
addClass:function(node){},
setText:function(node){}
}
参数
1 | var $div = $('div') |
要实现这个功能,需要区分传入的参数是一个选择器还是节点,并以伪数组的形式返回。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16window.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 (nodeOrSelector instanceof Node) {
nodes = {
0: nodeOrSelector,
length: 1
}
}
}
如果只是单单实现所需要的功能,可以简化成1
2
3window.jQuery = function (nodeOrSelector) {
let nodes = document.querySelectorAll(nodeOrSelector)
}
需求实现
1 | $div.addClass('red')// 可将所有 div 的 class 添加一个 red |
nodes是一个伪数组。如果每个div都要添加class的话,需要一个for循环,然后每一次用DOM的方法里的classList.add功能对div添加class。1
2
3
4
5addClass: function (className) {
for (let i = 0; i < nodes.length; i++) {
nodes[i].classList.add(className)
}
}
同理可实现1
2
3
4
5
6
7$div.setText('hi') // 可将所有 div 的 textContent 变为 hi
setText: function (text) {
for (let i = 0; i < nodes.length; i++) {
nodes[i].textContent=text
}
}
把addClass和setText的内容结合到函数内,得到: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
30window.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 (nodeOrSelector instanceof Node) {
nodes = {
0: nodeOrSelector,
length: 1
}
}
return {
addClass: function (className) {
for (let i = 0; i < nodes.length; i++) {
nodes[i].classList.add(className)
}
},
setText: function (text) {
for (let i = 0; i < nodes.length; i++) {
nodes[i].textContent=text
}
}
}
}
window.$ = jQuery