我用這篇文章來理一理如何用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來實現上面代碼的功能。我們分三步走戰略來實現。
- js實現 $(".box1")
- 實現 $(".box1").click()
- 實現 $(".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的過程大家應該清楚吧,我們溫習一下:
- 執行函數
- 自動創建一個空對象
- 將空對象的原型指向構造函數的prototype屬性
- 將空對象和函數內部this綁定
- 如果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