我用這篇文章來理一理如何用js去實現(xiàn)封裝jQuery的簡單方法。
本文js實現(xiàn)了下面jquery的幾種方法,我將它分為8個小目標
- 實現(xiàn)$(".box1").click( )方法
- 實現(xiàn)$("div").click( )方法
- 考慮$( )中參數(shù)的三種情況
- 實現(xiàn)jq中的on方法
- 實現(xiàn)鏈式操作
- 實現(xiàn)jq中的eq方法
- 實現(xiàn)jq中的end方法
- 實現(xiàn)jq中的css方法
有不正確的地方還望大家在評論區(qū)指出來,謝謝啦。
1. 實現(xiàn)$(".box1").click( )方法
首先,我們定第一個小目標,就是如何一步一步去實現(xiàn)下方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") 就是實現(xiàn)了選擇器的功能。
- $(".box1").click 就是選擇器 + 調用click方法
- 最后在click里面?zhèn)魅牒瘮?shù)。
第一個小目標就是自己封裝js來實現(xiàn)上面代碼的功能。我們分三步走戰(zhàn)略來實現(xiàn)。
- js實現(xiàn) $(".box1")
- 實現(xiàn) $(".box1").click()
- 實現(xiàn) $(".box1").click( ( ) => { console.log("123") } )
第一步就是先用js實現(xiàn) $(".box1"), 對吧
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
// 實現(xiàn)$(".box1") class jquery { constructor(arg) { console.log(document.querySelector(arg)); } } function $(arg) { return new jquery(arg); } // 實現(xiàn)$(".box1") let res = $( ".box1" ); console.log(res); |
這樣是不是就通過構建()方法并返回jquery實例,實現(xiàn)了(".box1")呢。
那好,接下來我們進行第二步就是實現(xiàn) $(".box1").click()。相信大家也看出來了,就是在jquery類中多了一個click方法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
// 實現(xiàn)$(".box1").click() class jquery { constructor(arg) { console.log(document.querySelector(arg)); } click() { console.log( "執(zhí)行了click方法" ); } } function $(arg) { return new jquery(arg); } // 實現(xiàn)$(".box1").click() let res = $( ".box1" ).click(); console.log(res); |
接下來,我們進行第三步就是實現(xiàn) $(".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
|
// 實現(xiàn)$(".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); } //實現(xiàn)$(".box1").click(() => {console.log("123")}) $( ".box1" ).click(() => { console.log( "123" ) }); |
到此為止,我們實現(xiàn)了第一個小目標,大家是不是覺得簡單呢,ok,接下來我們繼續(xù)第二個小目標。
2. 實現(xiàn)$("div").click( )方法
第二個小目標也不難,就是考慮有多個div元素需要綁定click事件,我們用selectSelectorAll來獲取元素的話,如何處理,其實也挺簡單,就是在click方法中多出一個循環(huán),去獲取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> // 實現(xiàn)$(".box1").click(() => {console.log("123")}) class jquery { constructor(arg) { //下面element存的是NodeList對象,它是一個類數(shù)組有l(wèi)ength屬性 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); } //實現(xiàn)$(".box1").click(() => {console.log("123")}) $( "div" ).click(() => { console.log( "123" ) }); </script> </html> |
好了,完成兩個小目標了,相信你已經(jīng)有成就感了。
3. 考慮$( )中參數(shù)的三種情況
接下來第三個小目標 我們來考慮一下$( )中參數(shù)不同的情況,我先將三種情況列出來。(可能還有其他情況,這里就不說了)
1.情況一:就是$( )參數(shù)為字符串
1
|
$( ".box1" ) |
2.情況二:就是$( )參數(shù)為函數(shù)的情況。
1
2
3
4
|
//參數(shù)為函數(shù) $( function () { console.log( "123" ); }) |
3.情況三:就是$( )參數(shù)為NodeList對象或selectSelect獲得的節(jié)點
1
2
3
4
5
6
7
|
// 情況三 $(document.querySelectorAll( "div" )).click(()=>{ console.log( "123" ); }) $(document.querySelector( "div" )).click(()=>{ console.log( "456" ); }) |
接下來第三個小目標是手寫函數(shù)來實現(xiàn)三種情況。 首先我們增加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; } // 實現(xiàn)$(".box1").click(() => {console.log("123")}) click(fn) { for (let i = 0; i < this .length; i++) { this [i].addEventListener( "click" , fn); } } |
接下來實現(xiàn)三種不同參數(shù)的處理方法
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. 實現(xiàn)jq中的on方法
接下來實現(xiàn)第四個小目標 實現(xiàn)jq的on方法
1
2
3
4
5
6
7
8
9
10
11
|
// on方法 on(eventName, fn) { let eventArray = eventName.split( " " ); //考慮多個節(jié)點 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. 實現(xiàn)鏈式操作
接下來實現(xiàn)第五個小目標 實現(xiàn)jq的鏈式操作
劃重點,在on和click中添加return this即可實現(xiàn)鏈式
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即可實現(xiàn)鏈式 // 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( " " ); //考慮多個節(jié)點 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. 實現(xiàn)jq中的eq方法
接下來實現(xiàn)第六個小目標 實現(xiàn)jq中的eq方法
1
2
3
4
|
//eq方法 eq(index) { return new jquery( this [index]); } |
這里通過new一個jquery實現(xiàn) new的過程大家應該清楚吧,我們溫習一下:
- 執(zhí)行函數(shù)
- 自動創(chuàng)建一個空對象
- 將空對象的原型指向構造函數(shù)的prototype屬性
- 將空對象和函數(shù)內部this綁定
- 如果renturn后跟著對象,返回這個對象。沒跟的話就自動返回this對象
7. 實現(xiàn)jq中的end方法
實現(xiàn)第七個小目標 實現(xiàn)jq中的end方法。要實現(xiàn)這個功能,除了新增end( )方法,我們還得在構造函數(shù)上實現(xiàn),constructor新增參數(shù)root,新增屬性prevObject,并在eq方法這種新增參數(shù)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. 實現(xiàn)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}); |
接下來實現(xiàn)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即可實現(xiàn)鏈式 // 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( " " ); //考慮多個節(jié)點 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 } // //實現(xiàn)情況一:$(".box1") // $("div").click(() => { // console.log("123") // }); // //實現(xiàn)情況二:參數(shù)為函數(shù) // $(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實現(xiàn)封裝jQuery的簡單方法與鏈式操作的文章就介紹到這了,更多相關js封裝jQuery內容請搜索服務器之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持服務器之家!
原文鏈接:https://segmentfault.com/a/119000003941249