首先有必要介绍一下jQuery,据统计在市面上近70%的公司的页面使用了jQuery这个库,所以还是有必要了解一下jQuery的使用方法以及一些特性。

jQuery的文档

原文地址

http://api.jquery.com/

译文地址

https://www.jquery123.com/

jQuery的类型

在页面引入jQuery之后用在控制台输入typeof jQuery得到的结果是'function'

所以jQuery的类型就是一个函数,那么既然jQuery是一个函数,我就可以用利用这个结果封装一个自己的简易的jQuery。

自己封装一个简单的jQuery

封装一个函数

node.getSiblings()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function getSiblings(node){
let allChildren = node.parentNode.children
let array = {
length: 0
}
for (let i = 0; i < allChildren.length; i++) {
if (allChildren[i] !== node) {
array[array.length] = allChildren[i] // 让输出的伪数组不包含本元素
array.length += 1
}
}
return array
}
//例如 li.getSiblings.call(li)

封装第二个函数

node.addClass()

1
2
3
4
5
function addClass(node, classes) {
classes.forEach( (value) => node.classList.add(value) )
//遍历节点 给所有节点添加或者单个节点添加类名
}
//例如 li.addClass.call(li,['a','b','c'])

命名问题

封装了一个函数总不能告诉大家 我今天写了一个库比较好用,大家都来用node.xxxx(),node.xx()来用这个库吧,所以需要一个命名空间。

1
2
3
4
5
6
7
8
let leeDom = {}  // 声明一个新对象
leeDom.getSiblings(node)
leeDom.addClass(node, ['a','b','c'])
// 把函数挂到对象下 引用方式直接leeDom.XXX()即可调用

// 然而我又觉得写leeDom很麻烦,要6个字符,所以我可以设置一个alisa
window.$ = leeDom
//这样是不是就很像jquery了?

我想把node放到前面怎么办?

类似于li.addClass('hi')这种更像jquery的写法。

方法一:

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

1
2
3
4
5
6
Node.prototype.addClass = function(classes){
classes.forEach((value)=>{node.classList.add(value)})
}
// 这样就可以通过 li.addClass('hi') 这样的方式来操作了
// 不过这样直接在原型链上修改不推荐,谁知道你会不会把别人写的函数给覆盖了,
// 或者把原本的函数给覆盖了
方法二:

新的接口 BetterNode

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
function Node2(node){
return {
element: node,
getSiblings: function(){

},
addClass: function(){

}
}
}
let node =document.getElementById('x')
let node2 = Node2(node)
node2.getSiblings()
node2.addClass()
// 这样可以完全避免在Node接口上操作

// 把Node 2 改成jQuery
function jQuery(node){
return {
element: node,
getSiblings: function(){

},
addClass: function(){

}
}
}

// 再来一个alisa

window.$ = jQuery

给自己写的jQuery添加text()功能

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
39
40
41
42
43
44
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 (nodeOrSelector instanceof Node) {
// 为了一致性 也输出伪数组
nodes = {
0: nodeOrSelector,
length: 1
}
}

nodes.getSiblings = function(){
}

nodes.addClass = function(classes) {
classes.forEach((value) =>{
for(let i = 0; i < nodes.length; i++){
nodes[i].classList.add(value) }
})
}

nodes.getText = function() {
let texts = []
for(let i = 0 ;i<nodes.length;i++){
texts.push(nodes[i].textContent)
}
return texts
}

nodes.setText = function(text){
for(let i = 0;i<nodes.length;i++){
nodes[i].textContent = text
}
}

return nodes
}

总结

我觉得jquery的好处不仅仅把很难操作的DOM变得容易操作了,还有他的链式操作也是很精髓的,比如
$(#div).addClass('active').removeClass('highlight')这样的操作,这种操作经常在CSS中用来切换样式。

__END__

o0Chivas0o
文章作者:o0Chivas0o
文章出处自己实现一个jQuery
作者签名:Rich ? DoSomethingLike() : DoSomethingNeed()
版权声明:文章除特别声明外,均采用 BY-NC-SA 许可协议,转载请注明出处