服务器之家:专注于服务器技术及软件下载分享
分类导航

node.js|vue.js|jquery|angularjs|React|json|js教程|

服务器之家 - 编程语言 - JavaScript - js教程 - js实现封装jQuery的简单方法与链式操作详解

js实现封装jQuery的简单方法与链式操作详解

2022-02-19 17:48李不要熬夜 js教程

这篇文章主要给大家介绍了关于js实现封装jQuery的简单方法与链式操作的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

我用这篇文章来理一理如何用js去实现封装jQuery的简单方法。

本文js实现了下面jquery的几种方法,我将它分为8个小目标

  • 实现$(".box1").click( )方法
  • 实现$("div").click( )方法
  • 考虑$( )中参数的三种情况
  • 实现jq中的on方法
  • 实现链式操作
  • 实现jq中的eq方法
  • 实现jq中的end方法
  • 实现jq中的css方法

有不正确的地方还望大家在评论区指出来,谢谢啦。

1. 实现$(".box1").click( )方法

首先,我们定第一个小目标,就是如何一步一步去实现下方jQuery代码的功能。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <title>Document</title>
 //同一个文件下操作的话,后面记得删除下面引入的cdn
 <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.0/jquery.min.js"></script>
 <style> .box1 {
  width: 100px;
  height: 100px;
  background: red;
 } </style>
</head>
<body>
 <div class="box1"></div>
</body>
<script> $(".box1").click(()=>{
 console.log(456);
 }) </script>
</html>
复制代码
?
1
2
3
$(".box1").click(()=>{
console.log(456);
})

好了,言归正传,我们来分析上面jQuery的代码。

  • $(".box1") 就是实现了选择器的功能。
  • $(".box1").click 就是选择器 + 调用click方法
  • 最后在click里面传入函数。

第一个小目标就是自己封装js来实现上面代码的功能。我们分三步走战略来实现。

  1. js实现 $(".box1")
  2. 实现 $(".box1").click()
  3. 实现 $(".box1").click( ( ) => { console.log("123") } )

第一步就是先用js实现 $(".box1"), 对吧

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 实现$(".box1")
class jquery {
constructor(arg) {
 console.log(document.querySelector(arg));
}
}
 
function $(arg) {
return new jquery(arg);
}
 
// 实现$(".box1")
let res = $(".box1");
console.log(res);

这样是不是就通过构建()方法并返回jquery实例,实现了(".box1")呢。

那好,接下来我们进行第二步就是实现 $(".box1").click()。相信大家也看出来了,就是在jquery类中多了一个click方法。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 实现$(".box1").click()
class jquery {
constructor(arg) {
 console.log(document.querySelector(arg));
}
 
click() {
 console.log("执行了click方法");
}
}
 
function $(arg) {
return new jquery(arg);
}
 
// 实现$(".box1").click()
let res = $(".box1").click();
console.log(res);

接下来,我们进行第三步就是实现 $(".box1").click( ( ) => { console.log("123") } )。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 实现$(".box1").click(() => {console.log("123")})
class jquery {
constructor(arg) {
 this.element = document.querySelector(arg);
 // console.log(element);
}
 
click(fn) {
 this.element.addEventListener("click", fn);
}
 
}
 
function $(arg) {
return new jquery(arg);
}
 
//实现$(".box1").click(() => {console.log("123")})
$(".box1").click(() => {
console.log("123")
});

到此为止,我们实现了第一个小目标,大家是不是觉得简单呢,ok,接下来我们继续第二个小目标。

2. 实现$("div").click( )方法

第二个小目标也不难,就是考虑有多个div元素需要绑定click事件,我们用selectSelectorAll来获取元素的话,如何处理,其实也挺简单,就是在click方法中多出一个循环,去获取NodeList中的值。我直接上代码了,大家试一试就知道啦。

?
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
45
46
47
48
49
<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <title>Document</title>
 <style> .box1 {
  width: 100px;
  height: 100px;
  background: red;
 }
 .box2 {
  width: 100px;
  height: 100px;
  background: blue;
 } </style>
</head>
 
<body>
 <div class="box1"></div>
 
 <div class="box2"></div>
</body>
 
<script> // 实现$(".box1").click(() => {console.log("123")})
 class jquery {
 constructor(arg) {
  //下面element存的是NodeList对象,它是一个类数组有length属性
  this.element = document.querySelectorAll(arg);
 }
 
 click(fn) {
  for(let i = 0; i < this.element.length; i++) {
  this.element[i].addEventListener("click", fn);
  
 }
 
 }
 
 function $(arg) {
 return new jquery(arg);
 }
 
 //实现$(".box1").click(() => {console.log("123")})
 $("div").click(() => {
 console.log("123")
 }); </script>
 
</html>

好了,完成两个小目标了,相信你已经有成就感了。

3. 考虑$( )中参数的三种情况

接下来第三个小目标 我们来考虑一下$( )中参数不同的情况,我先将三种情况列出来。(可能还有其他情况,这里就不说了)

1.情况一:就是$( )参数为字符串

?
1
$(".box1")

2.情况二:就是$( )参数为函数的情况。

?
1
2
3
4
//参数为函数
 $(function() {
 console.log("123");
 })

3.情况三:就是$( )参数为NodeList对象或selectSelect获得的节点

?
1
2
3
4
5
6
7
// 情况三
 $(document.querySelectorAll("div")).click(()=>{
 console.log("123");
 })
 $(document.querySelector("div")).click(()=>{
 console.log("456");
 })

接下来第三个小目标是手写函数来实现三种情况。 首先我们增加addEles方法,修改上面的click方法

?
1
2
3
4
5
6
7
8
9
10
11
12
13
addEles(eles){
  for (let i = 0; i < eles.length; i++) {
  this[i] = eles[i];
  }
  this.length = eles.length;
 }
 
 // 实现$(".box1").click(() => {console.log("123")})
 click(fn) {
  for(let i = 0; i < this.length; i++) {
  this[i].addEventListener("click", fn);
  
 }

接下来实现三种不同参数的处理方法

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
constructor(arg) {
 
  //情况一
  if(typeof arg === 'string') {
  this.addEles(document.querySelectorAll(arg));
  }else if(typeof arg === 'function') {
  //情况二
  document.addEventListener("DOMContentLoaded", arg);
  }else {
  //情况三
  if(typeof arg.length === 'undefined') {
   this[0] = arg;
   this.length = 1;
  }else {
   this.addEles(arg);
  }
  }
 
 }

4. 实现jq中的on方法

接下来实现第四个小目标 实现jq的on方法

?
1
2
3
4
5
6
7
8
9
10
11
// on方法
 on(eventName, fn) {
  let eventArray = eventName.split(" ");
  //考虑多个节点
  for(let i = 0; i < this.length; i++) {
  //考虑多个事件
  for(let j = 0; j < eventArray.length; j++) {
   this[i].addEventListener(eventArray[j], fn);
  }
  }
 }

再测试下ok不

?
1
2
3
4
// on方法
 $("div").on("mouseover mousedown",function(){
 console.log("on方法");
 })

5. 实现链式操作

接下来实现第五个小目标 实现jq的链式操作

划重点,在on和click中添加return this即可实现链式

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//链式操作
 //划重点,在on和click中添加return this即可实现链式
 // click方法
 click(fn) {
  for(let i = 0; i < this.length; i++) {
  this[i].addEventListener("click", fn);
  }
  return this;
  // console.log(this);
 }
 
 // on方法
 on(eventName, fn) {
  let eventArray = eventName.split(" ");
  //考虑多个节点
  for(let i = 0; i < this.length; i++) {
  //考虑多个事件
  for(let j = 0; j < eventArray.length; j++) {
   this[i].addEventListener(eventArray[j], fn);
  }
  }
  return this;
 }

6. 实现jq中的eq方法

接下来实现第六个小目标 实现jq中的eq方法

?
1
2
3
4
//eq方法
 eq(index) {
  return new jquery(this[index]);
 }

这里通过new一个jquery实现 new的过程大家应该清楚吧,我们温习一下:

  1. 执行函数
  2. 自动创建一个空对象
  3. 将空对象的原型指向构造函数的prototype属性
  4. 将空对象和函数内部this绑定
  5. 如果renturn后跟着对象,返回这个对象。没跟的话就自动返回this对象

7. 实现jq中的end方法

实现第七个小目标 实现jq中的end方法。要实现这个功能,除了新增end( )方法,我们还得在构造函数上实现,constructor新增参数root,新增属性prevObject,并在eq方法这种新增参数this。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
constructor(arg, root) {
  if(typeof root === "undefined") {
  this.prevObject = [document];
  }else {
  this.prevObject = root;
  }
 //eq方法
 eq(index) {
  return new jquery(this[index], this);
 }
 //end方法
 end() {
  return this.prevObject;
 }

8. 实现jq中的css方法

在jq中css可以获取样式,设置一个样式或多个样式

?
1
2
3
4
5
6
7
8
9
10
11
12
// 情况一 :获取样式 (只去获取第一个元素)
 
 let res = $("div").css("background");
 console.log(res);
 
// 情况二 (设置样式)
 
 $("div").css("background","yellow");
 
// // 情况三 (设置多个样式)
 
 $("div").css({background:"black",width:200,opacity:0.3});

接下来实现css方法

?
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
45
//css方法
 
 css(...args) {
  if(args.length === 1) {
 
  //情况一:获取样式
  if(typeof args[0] === 'string') {
   return this.getStyle(this[0], args[0]);
  }else {
   //情况三:设置多个样式
   for(let i = 0; i < this.length; i++) {
   for(let j in args[0]) {
    this.setStyle(this[i], j, args[0][j]);
   }
 
   }
  }
  }else {
  //情况三
  for(let i = 0; i < this.length; i++) {
   this.setStyle(this[i], args[0], args[1]);
  }
  }
 } //css方法
 css(...args) {
 if(args.length === 1) {
  //情况一:获取样式
  if(typeof args[0] === 'string') {
  return this.getStyle(this[0], args[0]);
  }else {
  //情况三:设置多个样式
  for(let i = 0; i < this.length; i++) {
   for(let j in args[0]) {
    this.setStyle(this[i], j, args[0][j]);
   }
 
  }
  }
 }else {
  //情况三
  for(let i = 0; i < this.length; i++) {
  this.setStyle(this[i], args[0], args[1]);
  }
 }
 }

增加cssNumber方法来确定不用加px的属性名

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//css方法用
 $.cssNumber = {
 animationIterationCount: true,
 columnCount: true,
 fillOpacity: true,
 flexGrow: true,
 flexShrink: true,
 fontWeight: true,
 gridArea: true,
 gridColumn: true,
 gridColumnEnd: true,
 gridColumnStart: true,
 gridRow: true,
 gridRowEnd: true,
 gridRowStart: true,
 lineHeight: true,
 opacity: true,
 order: true,
 orphans: true,
 widows: true,
 zIndex: true,
 zoom: true
}

最后献上完整代码,如果大哥们觉的不错,给个赞呗

?
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <title>Document</title>
 <style> .box1 {
  width: 100px;
  height: 100px;
  background: red;
 }
 .box2 {
  width: 100px;
  height: 100px;
  background: blue;
  transform-origin: 0 100% 0;
  transition: 0.3s;
 
 }
 .box2:hover {
  transform: scaleX(2);
  width: 200px;
  height: 100px;
 } </style>
</head>
 
<body>
 <div class="box1"></div>
 
 <div class="box2"></div>
 <button>点击</button>
</body>
 
<script> class jquery {
 
 constructor(arg, root) {
  if(typeof root === "undefined") {
  this.prevObject = [document];
  }else {
  this.prevObject = root;
  }
  //情况一
  if(typeof arg === 'string') {
  this.addEles(document.querySelectorAll(arg));
  }else if(typeof arg === 'function') {
  //情况二
  document.addEventListener("DOMContentLoaded", arg);
  }else {
  //情况三
  if(typeof arg.length === 'undefined') {
   this[0] = arg;
   this.length = 1;
  }else {
   this.addEles(arg);
  }
  }
 
 }
 
 //增加方法
 addEles(eles){
  for (let i = 0; i < eles.length; i++) {
  this[i] = eles[i];
  }
  this.length = eles.length;
 }
 
 //链式操作
 //划重点,在on和click中添加return即可实现链式
 // click方法
 click(fn) {
  for(let i = 0; i < this.length; i++) {
  this[i].addEventListener("click", fn);
  }
  return this;
  // console.log(this);
 }
 
 // on方法
 on(eventName, fn) {
  let eventArray = eventName.split(" ");
  //考虑多个节点
  for(let i = 0; i < this.length; i++) {
  //考虑多个事件
  for(let j = 0; j < eventArray.length; j++) {
   this[i].addEventListener(eventArray[j], fn);
  }
  }
  return this;
 }
 
 //eq方法
 eq(index) {
  return new jquery(this[index], this);
 }
 
 //end方法
 end() {
  return this.prevObject;
 }
 
 //css方法
 css(...args) {
  if(args.length === 1) {
 
  //情况一:获取样式
  if(typeof args[0] === 'string') {
   return this.getStyle(this[0], args[0]);
  }else {
   //情况三:设置多个样式
   for(let i = 0; i < this.length; i++) {
   for(let j in args[0]) {
    this.setStyle(this[i], j, args[0][j]);
   }
 
   }
  }
  }else {
  //情况三
  for(let i = 0; i < this.length; i++) {
   this.setStyle(this[i], args[0], args[1]);
  }
  }
 }
 
 getStyle(ele, styleName) {
  return window.getComputedStyle(ele, null)[styleName];
 }
 setStyle(ele, styleName, styleValue) {
  if(typeof styleValue === "number" && !(styleName in $.cssNumber)) {
  styleValue = styleValue + "px";
  }
  ele.style[styleName] = styleValue;
 }
 
 }
 
 function $(arg) {
 return new jquery(arg);
 }
 
 //css方法用
 $.cssNumber = {
 animationIterationCount: true,
 columnCount: true,
 fillOpacity: true,
 flexGrow: true,
 flexShrink: true,
 fontWeight: true,
 gridArea: true,
 gridColumn: true,
 gridColumnEnd: true,
 gridColumnStart: true,
 gridRow: true,
 gridRowEnd: true,
 gridRowStart: true,
 lineHeight: true,
 opacity: true,
 order: true,
 orphans: true,
 widows: true,
 zIndex: true,
 zoom: true
}
 // //实现情况一:$(".box1")
 // $("div").click(() => {
 // console.log("123")
 // });
 
 // //实现情况二:参数为函数
 // $(function() {
 // console.log('情况2');
 // })
 
 // // 情况三
 // $(document.querySelectorAll("div")).click(()=>{
 // console.log("123");
 // })
 // $(document.querySelector("div")).click(()=>{
 // console.log("456");
 // })
 
 // // on方法
 // $("div").on("mouseover mousedown",function(){
 // console.log("on方法");
 // })
 
 //链式操作
 // $("div").click(() => {
 // console.log("click方法")
 // }).on("mouseover", function() {
 // console.log('链式on方法');
 // })
 
 // $("div").on("mouseover", function() {
 // console.log('链式on方法');
 // }).click(() => {
 // console.log("click方法")
 // })
 
 // //eq方法
 // $("div").eq(0).click(() => {
 // console.log("eq方法")
 // })
 
 //endf方法
 // let res = $("div").eq(0).eq(0).eq(0).end();
 // console.log(res);
 
 //css方法
 
 // 情况一 :获取样式 (只去获取第一个元素)
 // let res = $("div").css("background");
 // console.log(res);
 
 // 情况二 (设置样式)
 // $("div").css("background","yellow");
 
 // // 情况三 (设置多个样式)
 // $("div").css({background:"black",width:200,opacity:0.3}); </script>
</html>

总结

到此这篇关于js实现封装jQuery的简单方法与链式操作的文章就介绍到这了,更多相关js封装jQuery内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://segmentfault.com/a/119000003941249

延伸 · 阅读

精彩推荐
  • js教程JS中循环遍历数组的四种方式总结

    JS中循环遍历数组的四种方式总结

    这篇文章主要给大家总结介绍了关于JS中循环遍历数组的四种方式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,...

    前端小混混5492022-01-06
  • js教程JS实现点击掉落特效

    JS实现点击掉落特效

    这篇文章主要介绍了JS实现点击掉落特效,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...

    小杨的旺仔没有牛奶11802022-01-11
  • js教程Javascript生成器(Generator)的介绍与使用

    Javascript生成器(Generator)的介绍与使用

    这篇文章主要给大家介绍了关于Javascript生成器(Generator)的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值...

    疯狂的技术宅3422022-01-12
  • js教程JavaScript如何实现防止重复的网络请求的示例

    JavaScript如何实现防止重复的网络请求的示例

    这篇文章主要介绍了JavaScript如何实现防止重复的网络请求的示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需...

    Daes11142022-01-10
  • js教程微信小程序弹窗禁止页面滚动的实现代码

    微信小程序弹窗禁止页面滚动的实现代码

    这篇文章主要介绍了微信小程序弹窗禁止页面滚动的实现代码,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需...

    任我行RQ5602021-12-23
  • js教程javascript实现简单页面倒计时

    javascript实现简单页面倒计时

    这篇文章主要为大家详细介绍了javascript实现简单页面倒计时,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    潜力股wjk11972022-01-25
  • js教程原生js 实现表单验证功能

    原生js 实现表单验证功能

    这篇文章主要介绍了原生js如何实现表单验证功能,帮助大家更好的理解和使用JavaScript,感兴趣的朋友可以了解下...

    蒋伟平7282022-01-19
  • js教程js实现简单图片拖拽效果

    js实现简单图片拖拽效果

    这篇文章主要为大家详细介绍了js实现简单图片拖拽效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    qq_448013368902022-01-22