@whitesev/domutils 1.6.5 → 1.6.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +42 -42
- package/dist/index.amd.js +267 -301
- package/dist/index.amd.js.map +1 -1
- package/dist/index.cjs.js +267 -301
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +267 -301
- package/dist/index.esm.js.map +1 -1
- package/dist/index.iife.js +267 -301
- package/dist/index.iife.js.map +1 -1
- package/dist/index.system.js +267 -301
- package/dist/index.system.js.map +1 -1
- package/dist/index.umd.js +267 -301
- package/dist/index.umd.js.map +1 -1
- package/dist/types/src/DOMUtils.d.ts +34 -5
- package/dist/types/src/DOMUtilsCommonUtils.d.ts +2 -2
- package/dist/types/src/DOMUtilsEvent.d.ts +64 -64
- package/dist/types/src/types/DOMUtilsEvent.d.ts +142 -142
- package/dist/types/src/types/WindowApi.d.ts +9 -9
- package/dist/types/src/types/global.d.ts +2 -10
- package/dist/types/src/types/gm.d.ts +5 -1
- package/index.ts +3 -0
- package/package.json +19 -7
- package/src/DOMUtils.ts +1967 -1974
- package/src/DOMUtilsCommonUtils.ts +196 -196
- package/src/DOMUtilsData.ts +2 -2
- package/src/DOMUtilsEvent.ts +1407 -1459
- package/src/DOMUtilsOriginPrototype.ts +3 -3
- package/src/WindowApi.ts +55 -55
- package/src/types/DOMUtilsEvent.d.ts +142 -142
- package/src/types/WindowApi.d.ts +9 -9
- package/src/types/global.d.ts +2 -10
- package/src/types/gm.d.ts +5 -1
package/src/DOMUtilsEvent.ts
CHANGED
|
@@ -2,1174 +2,1140 @@ import { DOMUtilsCommonUtils } from "./DOMUtilsCommonUtils";
|
|
|
2
2
|
import { DOMUtilsData } from "./DOMUtilsData";
|
|
3
3
|
import { OriginPrototype } from "./DOMUtilsOriginPrototype";
|
|
4
4
|
import type {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
DOMUtils_Event,
|
|
6
|
+
DOMUtils_EventType,
|
|
7
|
+
DOMUtilsElementEventType,
|
|
8
|
+
DOMUtilsEventListenerOption,
|
|
9
|
+
DOMUtilsEventListenerOptionsAttribute,
|
|
10
10
|
} from "./types/DOMUtilsEvent";
|
|
11
11
|
import type { DOMUtilsTargetElementType } from "./types/global";
|
|
12
12
|
import type { WindowApiOption } from "./types/WindowApi";
|
|
13
13
|
import { WindowApi } from "./WindowApi";
|
|
14
14
|
|
|
15
15
|
export class DOMUtilsEvent {
|
|
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
|
-
"isComposedPath" in currentParam)
|
|
176
|
-
) {
|
|
177
|
-
option.capture = currentParam.capture;
|
|
178
|
-
option.once = currentParam.once;
|
|
179
|
-
option.passive = currentParam.passive;
|
|
180
|
-
option.isComposedPath = currentParam.isComposedPath;
|
|
181
|
-
}
|
|
182
|
-
return option;
|
|
183
|
-
}
|
|
16
|
+
windowApi: typeof WindowApi.prototype;
|
|
17
|
+
constructor(windowApiOption?: WindowApiOption) {
|
|
18
|
+
this.windowApi = new WindowApi(windowApiOption);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* 绑定事件
|
|
22
|
+
* @param element 需要绑定的元素|元素数组|window
|
|
23
|
+
* @param eventType 需要监听的事件
|
|
24
|
+
* @param callback 绑定事件触发的回调函数
|
|
25
|
+
* @param option
|
|
26
|
+
* + capture 表示事件是否在捕获阶段触发。默认为false,即在冒泡阶段触发
|
|
27
|
+
* + once 表示事件是否只触发一次。默认为false
|
|
28
|
+
* + passive 表示事件监听器是否不会调用preventDefault()。默认为false
|
|
29
|
+
* @example
|
|
30
|
+
* // 监听元素a.xx的click事件
|
|
31
|
+
* DOMUtils.on(document.querySelector("a.xx"),"click",(event)=>{
|
|
32
|
+
* console.log("事件触发",event)
|
|
33
|
+
* })
|
|
34
|
+
* DOMUtils.on("a.xx","click",(event)=>{
|
|
35
|
+
* console.log("事件触发",event)
|
|
36
|
+
* })
|
|
37
|
+
*/
|
|
38
|
+
on<T extends DOMUtils_EventType>(
|
|
39
|
+
element: DOMUtilsElementEventType,
|
|
40
|
+
eventType: T | T[],
|
|
41
|
+
callback: (this: HTMLElement, event: DOMUtils_Event[T]) => void,
|
|
42
|
+
option?: DOMUtilsEventListenerOption | boolean
|
|
43
|
+
): void;
|
|
44
|
+
/**
|
|
45
|
+
* 绑定事件
|
|
46
|
+
* @param element 需要绑定的元素|元素数组|window
|
|
47
|
+
* @param eventType 需要监听的事件
|
|
48
|
+
* @param callback 绑定事件触发的回调函数
|
|
49
|
+
* @param option
|
|
50
|
+
* + capture 表示事件是否在捕获阶段触发。默认为false,即在冒泡阶段触发
|
|
51
|
+
* + once 表示事件是否只触发一次。默认为false
|
|
52
|
+
* + passive 表示事件监听器是否不会调用preventDefault()。默认为false
|
|
53
|
+
* @example
|
|
54
|
+
* // 监听元素a.xx的click事件
|
|
55
|
+
* DOMUtils.on(document.querySelector("a.xx"),"click",(event)=>{
|
|
56
|
+
* console.log("事件触发",event)
|
|
57
|
+
* })
|
|
58
|
+
* DOMUtils.on("a.xx","click",(event)=>{
|
|
59
|
+
* console.log("事件触发",event)
|
|
60
|
+
* })
|
|
61
|
+
*/
|
|
62
|
+
on<T extends Event>(
|
|
63
|
+
element: DOMUtilsElementEventType,
|
|
64
|
+
eventType: string | string[],
|
|
65
|
+
callback: (this: HTMLElement, event: T) => void,
|
|
66
|
+
option?: DOMUtilsEventListenerOption | boolean
|
|
67
|
+
): void;
|
|
68
|
+
/**
|
|
69
|
+
* 绑定事件
|
|
70
|
+
* @param element 需要绑定的元素|元素数组|window
|
|
71
|
+
* @param eventType 需要监听的事件
|
|
72
|
+
* @param selector 子元素选择器
|
|
73
|
+
* @param callback 绑定事件触发的回调函数
|
|
74
|
+
* @param option
|
|
75
|
+
* + capture 表示事件是否在捕获阶段触发。默认为false,即在冒泡阶段触发
|
|
76
|
+
* + once 表示事件是否只触发一次。默认为false
|
|
77
|
+
* + passive 表示事件监听器是否不会调用preventDefault()。默认为false
|
|
78
|
+
* @example
|
|
79
|
+
* // 监听元素a.xx的click、tap、hover事件
|
|
80
|
+
* DOMUtils.on(document.querySelector("a.xx"),"click tap hover",(event, selectorTarget)=>{
|
|
81
|
+
* console.log("事件触发", event, selectorTarget)
|
|
82
|
+
* })
|
|
83
|
+
* DOMUtils.on("a.xx",["click","tap","hover"],(event, selectorTarget)=>{
|
|
84
|
+
* console.log("事件触发", event, selectorTarget)
|
|
85
|
+
* })
|
|
86
|
+
* @example
|
|
87
|
+
* // 监听全局document下的子元素a.xx的click事件
|
|
88
|
+
* DOMUtils.on(document,"click tap hover","a.xx",(event, selectorTarget)=>{
|
|
89
|
+
* console.log("事件触发", event, selectorTarget)
|
|
90
|
+
* })
|
|
91
|
+
*/
|
|
92
|
+
on<T extends DOMUtils_EventType>(
|
|
93
|
+
element: DOMUtilsElementEventType,
|
|
94
|
+
eventType: T | T[],
|
|
95
|
+
selector: string | string[] | undefined | null,
|
|
96
|
+
callback: (this: HTMLElement, event: DOMUtils_Event[T], selectorTarget: HTMLElement) => void,
|
|
97
|
+
option?: DOMUtilsEventListenerOption | boolean
|
|
98
|
+
): void;
|
|
99
|
+
/**
|
|
100
|
+
* 绑定事件
|
|
101
|
+
* @param element 需要绑定的元素|元素数组|window
|
|
102
|
+
* @param eventType 需要监听的事件
|
|
103
|
+
* @param selector 子元素选择器
|
|
104
|
+
* @param callback 绑定事件触发的回调函数
|
|
105
|
+
* @param option
|
|
106
|
+
* + capture 表示事件是否在捕获阶段触发。默认为false,即在冒泡阶段触发
|
|
107
|
+
* + once 表示事件是否只触发一次。默认为false
|
|
108
|
+
* + passive 表示事件监听器是否不会调用preventDefault()。默认为false
|
|
109
|
+
* @example
|
|
110
|
+
* // 监听元素a.xx的click、tap、hover事件
|
|
111
|
+
* DOMUtils.on(document.querySelector("a.xx"),"click tap hover",(event, selectorTarget)=>{
|
|
112
|
+
* console.log("事件触发", event, selectorTarget)
|
|
113
|
+
* })
|
|
114
|
+
* DOMUtils.on("a.xx",["click","tap","hover"],(event, selectorTarget)=>{
|
|
115
|
+
* console.log("事件触发", event, selectorTarget)
|
|
116
|
+
* })
|
|
117
|
+
* @example
|
|
118
|
+
* // 监听全局document下的子元素a.xx的click事件
|
|
119
|
+
* DOMUtils.on(document,"click tap hover","a.xx",(event, selectorTarget)=>{
|
|
120
|
+
* console.log("事件触发", event, selectorTarget)
|
|
121
|
+
* })
|
|
122
|
+
*/
|
|
123
|
+
on<T extends Event>(
|
|
124
|
+
element: DOMUtilsElementEventType,
|
|
125
|
+
eventType: string | string[],
|
|
126
|
+
selector: string | string[] | undefined | null,
|
|
127
|
+
callback: (this: HTMLElement, event: T, selectorTarget: HTMLElement) => void,
|
|
128
|
+
option?: DOMUtilsEventListenerOption | boolean
|
|
129
|
+
): void;
|
|
130
|
+
on<T extends Event>(
|
|
131
|
+
element: HTMLElement | string | NodeList | HTMLElement[] | Window | Document | Element | null | typeof globalThis,
|
|
132
|
+
eventType: DOMUtils_EventType | DOMUtils_EventType[] | string | string[],
|
|
133
|
+
selector:
|
|
134
|
+
| string
|
|
135
|
+
| string[]
|
|
136
|
+
| undefined
|
|
137
|
+
| ((this: HTMLElement, event: T, selectorTarget: HTMLElement) => void)
|
|
138
|
+
| null,
|
|
139
|
+
callback?:
|
|
140
|
+
| ((this: HTMLElement, event: T, selectorTarget: HTMLElement) => void)
|
|
141
|
+
| DOMUtilsEventListenerOption
|
|
142
|
+
| boolean,
|
|
143
|
+
option?: DOMUtilsEventListenerOption | boolean
|
|
144
|
+
) {
|
|
145
|
+
/**
|
|
146
|
+
* 获取option配置
|
|
147
|
+
* @param args
|
|
148
|
+
* @param startIndex
|
|
149
|
+
* @param option
|
|
150
|
+
*/
|
|
151
|
+
function getOption(args: IArguments, startIndex: number, option: DOMUtilsEventListenerOption) {
|
|
152
|
+
const currentParam = args[startIndex];
|
|
153
|
+
if (typeof currentParam === "boolean") {
|
|
154
|
+
option.capture = currentParam;
|
|
155
|
+
if (typeof args[startIndex + 1] === "boolean") {
|
|
156
|
+
option.once = args[startIndex + 1];
|
|
157
|
+
}
|
|
158
|
+
if (typeof args[startIndex + 2] === "boolean") {
|
|
159
|
+
option.passive = args[startIndex + 2];
|
|
160
|
+
}
|
|
161
|
+
} else if (
|
|
162
|
+
typeof currentParam === "object" &&
|
|
163
|
+
("capture" in currentParam ||
|
|
164
|
+
"once" in currentParam ||
|
|
165
|
+
"passive" in currentParam ||
|
|
166
|
+
"isComposedPath" in currentParam)
|
|
167
|
+
) {
|
|
168
|
+
option.capture = currentParam.capture;
|
|
169
|
+
option.once = currentParam.once;
|
|
170
|
+
option.passive = currentParam.passive;
|
|
171
|
+
option.isComposedPath = currentParam.isComposedPath;
|
|
172
|
+
}
|
|
173
|
+
return option;
|
|
174
|
+
}
|
|
184
175
|
|
|
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
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
}
|
|
298
|
-
}
|
|
176
|
+
const DOMUtilsContext = this;
|
|
177
|
+
// eslint-disable-next-line prefer-rest-params
|
|
178
|
+
const args = arguments;
|
|
179
|
+
if (typeof element === "string") {
|
|
180
|
+
element = DOMUtilsContext.selectorAll(element);
|
|
181
|
+
}
|
|
182
|
+
if (element == null) {
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
let elementList: HTMLElement[] = [];
|
|
186
|
+
if (element instanceof NodeList || Array.isArray(element)) {
|
|
187
|
+
element = element as HTMLElement[];
|
|
188
|
+
elementList = [...element];
|
|
189
|
+
} else {
|
|
190
|
+
elementList.push(element as HTMLElement);
|
|
191
|
+
}
|
|
192
|
+
// 事件名
|
|
193
|
+
let eventTypeList: string[] = [];
|
|
194
|
+
if (Array.isArray(eventType)) {
|
|
195
|
+
eventTypeList = eventTypeList.concat(
|
|
196
|
+
eventType.filter((eventTypeItem) => typeof eventTypeItem === "string" && eventTypeItem.toString() !== "")
|
|
197
|
+
);
|
|
198
|
+
} else if (typeof eventType === "string") {
|
|
199
|
+
eventTypeList = eventTypeList.concat(eventType.split(" ").filter((eventTypeItem) => eventTypeItem !== ""));
|
|
200
|
+
}
|
|
201
|
+
// 子元素选择器
|
|
202
|
+
let selectorList: string[] = [];
|
|
203
|
+
if (Array.isArray(selector)) {
|
|
204
|
+
selectorList = selectorList.concat(
|
|
205
|
+
selector.filter((selectorItem) => typeof selectorItem === "string" && selectorItem.toString() !== "")
|
|
206
|
+
);
|
|
207
|
+
} else if (typeof selector === "string") {
|
|
208
|
+
selectorList.push(selector);
|
|
209
|
+
}
|
|
210
|
+
// 事件回调
|
|
211
|
+
let listenerCallBack: (this: HTMLElement, event: Event, selectorTarget?: HTMLElement) => void = callback as any;
|
|
212
|
+
// 事件配置
|
|
213
|
+
let listenerOption: DOMUtilsEventListenerOption = {
|
|
214
|
+
capture: false,
|
|
215
|
+
once: false,
|
|
216
|
+
passive: false,
|
|
217
|
+
isComposedPath: false,
|
|
218
|
+
};
|
|
219
|
+
if (typeof selector === "function") {
|
|
220
|
+
// 这是为没有selector的情况
|
|
221
|
+
// 那么它就是callback
|
|
222
|
+
listenerCallBack = selector as any;
|
|
223
|
+
listenerOption = getOption(args, 3, listenerOption);
|
|
224
|
+
} else {
|
|
225
|
+
// 这是存在selector的情况
|
|
226
|
+
listenerOption = getOption(args, 4, listenerOption);
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* 如果是once,那么删除该监听和元素上的事件和监听
|
|
230
|
+
*/
|
|
231
|
+
function checkOptionOnceToRemoveEventListener() {
|
|
232
|
+
if (listenerOption.once) {
|
|
233
|
+
DOMUtilsContext.off(element, eventType as any, selector as any, callback as any, option);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
elementList.forEach((elementItem) => {
|
|
237
|
+
/**
|
|
238
|
+
* 事件回调
|
|
239
|
+
* @param event
|
|
240
|
+
*/
|
|
241
|
+
function domUtilsEventCallBack(event: Event) {
|
|
242
|
+
if (selectorList.length) {
|
|
243
|
+
/* 存在子元素选择器 */
|
|
244
|
+
// 这时候的this和target都是子元素选择器的元素
|
|
245
|
+
let eventTarget = listenerOption.isComposedPath
|
|
246
|
+
? (event.composedPath()[0] as HTMLElement)
|
|
247
|
+
: (event.target as HTMLElement);
|
|
248
|
+
let totalParent = elementItem;
|
|
249
|
+
if (DOMUtilsCommonUtils.isWin(totalParent)) {
|
|
250
|
+
if (totalParent === (DOMUtilsContext.windowApi.document as any as HTMLElement)) {
|
|
251
|
+
totalParent = DOMUtilsContext.windowApi.document.documentElement;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
const findValue = selectorList.find((selectorItem) => {
|
|
255
|
+
// 判断目标元素是否匹配选择器
|
|
256
|
+
if (DOMUtilsContext.matches(eventTarget, selectorItem)) {
|
|
257
|
+
/* 当前目标可以被selector所匹配到 */
|
|
258
|
+
return true;
|
|
259
|
+
}
|
|
260
|
+
/* 在上层与主元素之间寻找可以被selector所匹配到的 */
|
|
261
|
+
const $closestMatches = DOMUtilsContext.closest<HTMLElement>(eventTarget, selectorItem);
|
|
262
|
+
if ($closestMatches && totalParent?.contains($closestMatches)) {
|
|
263
|
+
eventTarget = $closestMatches;
|
|
264
|
+
return true;
|
|
265
|
+
}
|
|
266
|
+
return false;
|
|
267
|
+
});
|
|
268
|
+
if (findValue) {
|
|
269
|
+
// 这里尝试使用defineProperty修改event的target值
|
|
270
|
+
try {
|
|
271
|
+
OriginPrototype.Object.defineProperty(event, "target", {
|
|
272
|
+
get() {
|
|
273
|
+
return eventTarget;
|
|
274
|
+
},
|
|
275
|
+
});
|
|
276
|
+
} catch {
|
|
277
|
+
// TODO
|
|
278
|
+
}
|
|
279
|
+
listenerCallBack.call(eventTarget, event as any, eventTarget);
|
|
280
|
+
checkOptionOnceToRemoveEventListener();
|
|
281
|
+
}
|
|
282
|
+
} else {
|
|
283
|
+
// 这时候的this指向监听的元素
|
|
284
|
+
listenerCallBack.call(elementItem, event as any);
|
|
285
|
+
checkOptionOnceToRemoveEventListener();
|
|
286
|
+
}
|
|
287
|
+
}
|
|
299
288
|
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
);
|
|
497
|
-
}
|
|
498
|
-
// 子元素选择器
|
|
499
|
-
let selectorList: string[] = [];
|
|
500
|
-
if (Array.isArray(selector)) {
|
|
501
|
-
selectorList = selectorList.concat(
|
|
502
|
-
selector.filter((selectorItem) => typeof selectorItem === "string" && selectorItem.toString() !== "")
|
|
503
|
-
);
|
|
504
|
-
} else if (typeof selector === "string") {
|
|
505
|
-
selectorList.push(selector);
|
|
506
|
-
}
|
|
507
|
-
/**
|
|
508
|
-
* 事件的回调函数
|
|
509
|
-
*/
|
|
510
|
-
let listenerCallBack: (this: HTMLElement, event: T, selectorTarget: HTMLElement) => void =
|
|
511
|
-
callback as any;
|
|
289
|
+
/* 遍历事件名设置元素事件 */
|
|
290
|
+
eventTypeList.forEach((eventName) => {
|
|
291
|
+
elementItem.addEventListener(eventName, domUtilsEventCallBack, listenerOption);
|
|
292
|
+
/* 获取对象上的事件 */
|
|
293
|
+
const elementEvents: {
|
|
294
|
+
[k: string]: DOMUtilsEventListenerOptionsAttribute[];
|
|
295
|
+
} = Reflect.get(elementItem, DOMUtilsData.SymbolEvents) || {};
|
|
296
|
+
/* 初始化对象上的xx事件 */
|
|
297
|
+
elementEvents[eventName] = elementEvents[eventName] || [];
|
|
298
|
+
elementEvents[eventName].push({
|
|
299
|
+
selector: selectorList,
|
|
300
|
+
option: listenerOption,
|
|
301
|
+
callback: domUtilsEventCallBack,
|
|
302
|
+
originCallBack: listenerCallBack,
|
|
303
|
+
});
|
|
304
|
+
/* 覆盖事件 */
|
|
305
|
+
Reflect.set(elementItem, DOMUtilsData.SymbolEvents, elementEvents);
|
|
306
|
+
});
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* 取消绑定事件
|
|
311
|
+
* @param element 需要取消绑定的元素|元素数组
|
|
312
|
+
* @param eventType 需要取消监听的事件
|
|
313
|
+
* @param callback 通过DOMUtils.on绑定的事件函数
|
|
314
|
+
* @param option
|
|
315
|
+
* + capture 如果在添加事件监听器时指定了useCapture为true,则在移除事件监听器时也必须指定为true
|
|
316
|
+
* @param filter (可选)过滤函数,对元素属性上的事件进行过滤出想要删除的事件
|
|
317
|
+
* @example
|
|
318
|
+
* // 取消监听元素a.xx所有的click事件
|
|
319
|
+
* DOMUtils.off(document.querySelector("a.xx"),"click")
|
|
320
|
+
* DOMUtils.off("a.xx","click")
|
|
321
|
+
*/
|
|
322
|
+
off<T extends DOMUtils_EventType>(
|
|
323
|
+
element: DOMUtilsElementEventType,
|
|
324
|
+
eventType: T | T[],
|
|
325
|
+
callback?: (this: HTMLElement, event: DOMUtils_Event[T]) => void,
|
|
326
|
+
option?: EventListenerOptions | boolean,
|
|
327
|
+
filter?: (
|
|
328
|
+
value: DOMUtilsEventListenerOptionsAttribute,
|
|
329
|
+
index: number,
|
|
330
|
+
array: DOMUtilsEventListenerOptionsAttribute[]
|
|
331
|
+
) => boolean
|
|
332
|
+
): void;
|
|
333
|
+
/**
|
|
334
|
+
* 取消绑定事件
|
|
335
|
+
* @param element 需要取消绑定的元素|元素数组
|
|
336
|
+
* @param eventType 需要取消监听的事件
|
|
337
|
+
* @param callback 通过DOMUtils.on绑定的事件函数
|
|
338
|
+
* @param option
|
|
339
|
+
* + capture 如果在添加事件监听器时指定了useCapture为true,则在移除事件监听器时也必须指定为true
|
|
340
|
+
* @param filter (可选)过滤函数,对元素属性上的事件进行过滤出想要删除的事件
|
|
341
|
+
* @example
|
|
342
|
+
* // 取消监听元素a.xx的click事件
|
|
343
|
+
* DOMUtils.off(document.querySelector("a.xx"),"click")
|
|
344
|
+
* DOMUtils.off("a.xx","click")
|
|
345
|
+
*/
|
|
346
|
+
off<T extends Event>(
|
|
347
|
+
element: DOMUtilsElementEventType,
|
|
348
|
+
eventType: string | string[],
|
|
349
|
+
callback?: (this: HTMLElement, event: T) => void,
|
|
350
|
+
option?: EventListenerOptions | boolean,
|
|
351
|
+
filter?: (
|
|
352
|
+
value: DOMUtilsEventListenerOptionsAttribute,
|
|
353
|
+
index: number,
|
|
354
|
+
array: DOMUtilsEventListenerOptionsAttribute[]
|
|
355
|
+
) => boolean
|
|
356
|
+
): void;
|
|
357
|
+
/**
|
|
358
|
+
* 取消绑定事件
|
|
359
|
+
* @param element 需要取消绑定的元素|元素数组
|
|
360
|
+
* @param eventType 需要取消监听的事件
|
|
361
|
+
* @param selector 子元素选择器
|
|
362
|
+
* @param callback 通过DOMUtils.on绑定的事件函数
|
|
363
|
+
* @param option
|
|
364
|
+
* + capture 如果在添加事件监听器时指定了useCapture为true,则在移除事件监听器时也必须指定为true
|
|
365
|
+
* @param filter (可选)过滤函数,对元素属性上的事件进行过滤出想要删除的事件
|
|
366
|
+
* @example
|
|
367
|
+
* // 取消监听元素a.xx的click、tap、hover事件
|
|
368
|
+
* DOMUtils.off(document.querySelector("a.xx"),"click tap hover")
|
|
369
|
+
* DOMUtils.off("a.xx",["click","tap","hover"])
|
|
370
|
+
*/
|
|
371
|
+
off<T extends DOMUtils_EventType>(
|
|
372
|
+
element: DOMUtilsElementEventType,
|
|
373
|
+
eventType: T | T[],
|
|
374
|
+
selector?: string | string[] | undefined | null,
|
|
375
|
+
callback?: (this: HTMLElement, event: DOMUtils_Event[T], selectorTarget: HTMLElement) => void,
|
|
376
|
+
option?: EventListenerOptions | boolean,
|
|
377
|
+
filter?: (
|
|
378
|
+
value: DOMUtilsEventListenerOptionsAttribute,
|
|
379
|
+
index: number,
|
|
380
|
+
array: DOMUtilsEventListenerOptionsAttribute[]
|
|
381
|
+
) => boolean
|
|
382
|
+
): void;
|
|
383
|
+
/**
|
|
384
|
+
* 取消绑定事件
|
|
385
|
+
* @param element 需要取消绑定的元素|元素数组
|
|
386
|
+
* @param eventType 需要取消监听的事件
|
|
387
|
+
* @param selector 子元素选择器
|
|
388
|
+
* @param callback 通过DOMUtils.on绑定的事件函数
|
|
389
|
+
* @param option
|
|
390
|
+
* + capture 如果在添加事件监听器时指定了useCapture为true,则在移除事件监听器时也必须指定为true
|
|
391
|
+
* @param filter (可选)过滤函数,对元素属性上的事件进行过滤出想要删除的事件
|
|
392
|
+
* @example
|
|
393
|
+
* // 取消监听元素a.xx的click、tap、hover事件
|
|
394
|
+
* DOMUtils.off(document.querySelector("a.xx"),"click tap hover")
|
|
395
|
+
* DOMUtils.off("a.xx",["click","tap","hover"])
|
|
396
|
+
*/
|
|
397
|
+
off<T extends Event>(
|
|
398
|
+
element: DOMUtilsElementEventType,
|
|
399
|
+
eventType: string | string[],
|
|
400
|
+
selector?: string | string[] | undefined | null,
|
|
401
|
+
callback?: (this: HTMLElement, event: T, selectorTarget: HTMLElement) => void,
|
|
402
|
+
option?: EventListenerOptions | boolean,
|
|
403
|
+
filter?: (
|
|
404
|
+
value: DOMUtilsEventListenerOptionsAttribute,
|
|
405
|
+
index: number,
|
|
406
|
+
array: DOMUtilsEventListenerOptionsAttribute[]
|
|
407
|
+
) => boolean
|
|
408
|
+
): void;
|
|
409
|
+
off<T extends Event>(
|
|
410
|
+
element: HTMLElement | string | NodeList | HTMLElement[] | Window | Document | Element | null | typeof globalThis,
|
|
411
|
+
eventType: DOMUtils_EventType | DOMUtils_EventType[] | string | string[],
|
|
412
|
+
selector:
|
|
413
|
+
| string
|
|
414
|
+
| string[]
|
|
415
|
+
| undefined
|
|
416
|
+
| ((this: HTMLElement, event: T, selectorTarget: HTMLElement) => void)
|
|
417
|
+
| null,
|
|
418
|
+
callback?: ((this: HTMLElement, event: T, selectorTarget: HTMLElement) => void) | EventListenerOptions | boolean,
|
|
419
|
+
option?:
|
|
420
|
+
| EventListenerOptions
|
|
421
|
+
| boolean
|
|
422
|
+
| ((
|
|
423
|
+
value: DOMUtilsEventListenerOptionsAttribute,
|
|
424
|
+
index: number,
|
|
425
|
+
array: DOMUtilsEventListenerOptionsAttribute[]
|
|
426
|
+
) => boolean),
|
|
427
|
+
filter?: (
|
|
428
|
+
value: DOMUtilsEventListenerOptionsAttribute,
|
|
429
|
+
index: number,
|
|
430
|
+
array: DOMUtilsEventListenerOptionsAttribute[]
|
|
431
|
+
) => boolean
|
|
432
|
+
) {
|
|
433
|
+
/**
|
|
434
|
+
* 获取option配置
|
|
435
|
+
* @param args1
|
|
436
|
+
* @param startIndex
|
|
437
|
+
* @param option
|
|
438
|
+
*/
|
|
439
|
+
function getOption(args1: IArguments, startIndex: number, option: EventListenerOptions) {
|
|
440
|
+
const currentParam: EventListenerOptions | boolean = args1[startIndex];
|
|
441
|
+
if (typeof currentParam === "boolean") {
|
|
442
|
+
option.capture = currentParam;
|
|
443
|
+
} else if (typeof currentParam === "object" && "capture" in currentParam) {
|
|
444
|
+
option.capture = currentParam.capture;
|
|
445
|
+
}
|
|
446
|
+
return option;
|
|
447
|
+
}
|
|
448
|
+
const DOMUtilsContext = this;
|
|
449
|
+
// eslint-disable-next-line prefer-rest-params
|
|
450
|
+
const args = arguments;
|
|
451
|
+
if (typeof element === "string") {
|
|
452
|
+
element = DOMUtilsContext.selectorAll(element);
|
|
453
|
+
}
|
|
454
|
+
if (element == null) {
|
|
455
|
+
return;
|
|
456
|
+
}
|
|
457
|
+
let elementList: HTMLElement[] = [];
|
|
458
|
+
if (element instanceof NodeList || Array.isArray(element)) {
|
|
459
|
+
element = element as HTMLElement[];
|
|
460
|
+
elementList = [...element];
|
|
461
|
+
} else {
|
|
462
|
+
elementList.push(element as HTMLElement);
|
|
463
|
+
}
|
|
464
|
+
let eventTypeList: string[] = [];
|
|
465
|
+
if (Array.isArray(eventType)) {
|
|
466
|
+
eventTypeList = eventTypeList.concat(
|
|
467
|
+
eventType.filter((eventTypeItem) => typeof eventTypeItem === "string" && eventTypeItem.toString() !== "")
|
|
468
|
+
);
|
|
469
|
+
} else if (typeof eventType === "string") {
|
|
470
|
+
eventTypeList = eventTypeList.concat(eventType.split(" ").filter((eventTypeItem) => eventTypeItem !== ""));
|
|
471
|
+
}
|
|
472
|
+
// 子元素选择器
|
|
473
|
+
let selectorList: string[] = [];
|
|
474
|
+
if (Array.isArray(selector)) {
|
|
475
|
+
selectorList = selectorList.concat(
|
|
476
|
+
selector.filter((selectorItem) => typeof selectorItem === "string" && selectorItem.toString() !== "")
|
|
477
|
+
);
|
|
478
|
+
} else if (typeof selector === "string") {
|
|
479
|
+
selectorList.push(selector);
|
|
480
|
+
}
|
|
481
|
+
/**
|
|
482
|
+
* 事件的回调函数
|
|
483
|
+
*/
|
|
484
|
+
let listenerCallBack: (this: HTMLElement, event: T, selectorTarget: HTMLElement) => void = callback as any;
|
|
512
485
|
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
486
|
+
/**
|
|
487
|
+
* 事件的配置
|
|
488
|
+
*/
|
|
489
|
+
let listenerOption: EventListenerOptions = {
|
|
490
|
+
capture: false,
|
|
491
|
+
};
|
|
492
|
+
if (typeof selector === "function") {
|
|
493
|
+
// 这是为没有selector的情况
|
|
494
|
+
// 那么它就是callback
|
|
495
|
+
listenerCallBack = selector;
|
|
496
|
+
listenerOption = getOption(args, 3, listenerOption);
|
|
497
|
+
} else {
|
|
498
|
+
// 这是存在selector的情况
|
|
499
|
+
listenerOption = getOption(args, 4, listenerOption);
|
|
500
|
+
}
|
|
501
|
+
// 是否移除所有事件
|
|
502
|
+
let isRemoveAll = false;
|
|
503
|
+
if (args.length === 2) {
|
|
504
|
+
// 目标函数、事件名
|
|
505
|
+
isRemoveAll = true;
|
|
506
|
+
} else if ((args.length === 3 && typeof args[2] === "string") || Array.isArray(args[2])) {
|
|
507
|
+
// 目标函数、事件名、子元素选择器
|
|
508
|
+
isRemoveAll = true;
|
|
509
|
+
}
|
|
510
|
+
elementList.forEach((elementItem) => {
|
|
511
|
+
/* 获取对象上的事件 */
|
|
512
|
+
const elementEvents: {
|
|
513
|
+
[key: string]: DOMUtilsEventListenerOptionsAttribute[];
|
|
514
|
+
} = Reflect.get(elementItem, DOMUtilsData.SymbolEvents) || {};
|
|
515
|
+
eventTypeList.forEach((eventName) => {
|
|
516
|
+
let handlers = elementEvents[eventName] || [];
|
|
517
|
+
if (typeof filter === "function") {
|
|
518
|
+
handlers = handlers.filter(filter);
|
|
519
|
+
}
|
|
520
|
+
for (let index = 0; index < handlers.length; index++) {
|
|
521
|
+
const handler = handlers[index];
|
|
522
|
+
let flag = true;
|
|
523
|
+
if (flag && listenerCallBack && handler.originCallBack !== listenerCallBack) {
|
|
524
|
+
// callback不同
|
|
525
|
+
flag = false;
|
|
526
|
+
}
|
|
527
|
+
if (flag && selectorList.length && Array.isArray(handler.selector)) {
|
|
528
|
+
if (JSON.stringify(handler.selector) !== JSON.stringify(selectorList)) {
|
|
529
|
+
// 子元素选择器不同
|
|
530
|
+
flag = false;
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
if (flag && listenerOption.capture !== handler.option.capture) {
|
|
534
|
+
// 事件的配置项不同
|
|
535
|
+
flag = false;
|
|
536
|
+
}
|
|
537
|
+
if (flag || isRemoveAll) {
|
|
538
|
+
elementItem.removeEventListener(eventName, handler.callback, handler.option);
|
|
539
|
+
handlers.splice(index--, 1);
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
if (handlers.length === 0) {
|
|
543
|
+
/* 如果没有任意的handler,那么删除该属性 */
|
|
544
|
+
DOMUtilsCommonUtils.delete(elementEvents, eventType);
|
|
545
|
+
}
|
|
546
|
+
});
|
|
547
|
+
Reflect.set(elementItem, DOMUtilsData.SymbolEvents, elementEvents);
|
|
548
|
+
});
|
|
549
|
+
}
|
|
550
|
+
/**
|
|
551
|
+
* 取消绑定所有的事件
|
|
552
|
+
* @param element 需要取消绑定的元素|元素数组
|
|
553
|
+
* @param eventType (可选)需要取消监听的事件
|
|
554
|
+
*/
|
|
555
|
+
offAll(element: DOMUtilsElementEventType, eventType?: string): void;
|
|
556
|
+
/**
|
|
557
|
+
* 取消绑定所有的事件
|
|
558
|
+
* @param element 需要取消绑定的元素|元素数组
|
|
559
|
+
* @param eventType (可选)需要取消监听的事件
|
|
560
|
+
*/
|
|
561
|
+
offAll(element: DOMUtilsElementEventType, eventType?: DOMUtils_EventType | DOMUtils_EventType[]): void;
|
|
562
|
+
/**
|
|
563
|
+
* 取消绑定所有的事件
|
|
564
|
+
* @param element 需要取消绑定的元素|元素数组
|
|
565
|
+
* @param eventType (可选)需要取消监听的事件
|
|
566
|
+
*/
|
|
567
|
+
offAll(element: DOMUtilsElementEventType, eventType?: DOMUtils_EventType | DOMUtils_EventType[] | string) {
|
|
568
|
+
const DOMUtilsContext = this;
|
|
569
|
+
if (typeof element === "string") {
|
|
570
|
+
element = DOMUtilsContext.selectorAll(element);
|
|
571
|
+
}
|
|
572
|
+
if (element == null) {
|
|
573
|
+
return;
|
|
574
|
+
}
|
|
575
|
+
let elementList: HTMLElement[] = [];
|
|
576
|
+
if (element instanceof NodeList || Array.isArray(element)) {
|
|
577
|
+
elementList = [...(element as HTMLElement[])];
|
|
578
|
+
} else {
|
|
579
|
+
elementList.push(element as HTMLElement);
|
|
580
|
+
}
|
|
608
581
|
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
582
|
+
let eventTypeList: string[] = [];
|
|
583
|
+
if (Array.isArray(eventType)) {
|
|
584
|
+
eventTypeList = eventTypeList.concat(eventType as string[]);
|
|
585
|
+
} else if (typeof eventType === "string") {
|
|
586
|
+
eventTypeList = eventTypeList.concat(eventType.split(" "));
|
|
587
|
+
}
|
|
588
|
+
elementList.forEach((elementItem) => {
|
|
589
|
+
Object.getOwnPropertySymbols(elementItem).forEach((symbolEvents) => {
|
|
590
|
+
if (!symbolEvents.toString().startsWith("Symbol(events_")) {
|
|
591
|
+
return;
|
|
592
|
+
}
|
|
593
|
+
const elementEvents = (elementItem as any)[symbolEvents] || {};
|
|
594
|
+
const iterEventNameList = eventTypeList.length ? eventTypeList : Object.keys(elementEvents);
|
|
595
|
+
iterEventNameList.forEach((eventName) => {
|
|
596
|
+
const handlers: DOMUtilsEventListenerOptionsAttribute[] = elementEvents[eventName];
|
|
597
|
+
if (!handlers) {
|
|
598
|
+
return;
|
|
599
|
+
}
|
|
600
|
+
for (const handler of handlers) {
|
|
601
|
+
elementItem.removeEventListener(eventName, handler.callback, {
|
|
602
|
+
capture: handler["option"]["capture"],
|
|
603
|
+
});
|
|
604
|
+
}
|
|
605
|
+
const events = Reflect.get(elementItem, symbolEvents);
|
|
606
|
+
DOMUtilsCommonUtils.delete(events, eventName);
|
|
607
|
+
});
|
|
608
|
+
});
|
|
609
|
+
});
|
|
610
|
+
}
|
|
638
611
|
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
612
|
+
/**
|
|
613
|
+
* 等待文档加载完成后执行指定的函数
|
|
614
|
+
* @param callback 需要执行的函数
|
|
615
|
+
* @example
|
|
616
|
+
* DOMUtils.ready(function(){
|
|
617
|
+
* console.log("文档加载完毕")
|
|
618
|
+
* })
|
|
619
|
+
*/
|
|
620
|
+
ready<T extends (...args: any[]) => any>(callback: T) {
|
|
621
|
+
if (typeof callback !== "function") {
|
|
622
|
+
return;
|
|
623
|
+
}
|
|
624
|
+
const DOMUtilsContext = this;
|
|
625
|
+
/**
|
|
626
|
+
* 检测文档是否加载完毕
|
|
627
|
+
*/
|
|
628
|
+
function checkDOMReadyState() {
|
|
629
|
+
try {
|
|
630
|
+
if (
|
|
631
|
+
DOMUtilsContext.windowApi.document.readyState === "complete" ||
|
|
632
|
+
(DOMUtilsContext.windowApi.document.readyState !== "loading" &&
|
|
633
|
+
!(DOMUtilsContext.windowApi.document.documentElement as any).doScroll)
|
|
634
|
+
) {
|
|
635
|
+
return true;
|
|
636
|
+
} else {
|
|
637
|
+
return false;
|
|
638
|
+
}
|
|
639
|
+
} catch {
|
|
640
|
+
return false;
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
/**
|
|
644
|
+
* 成功加载完毕后触发的回调函数
|
|
645
|
+
*/
|
|
646
|
+
function completed() {
|
|
647
|
+
removeDomReadyListener();
|
|
648
|
+
callback();
|
|
649
|
+
}
|
|
677
650
|
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
}
|
|
797
|
-
let eventTypeList: string[] = [];
|
|
798
|
-
if (Array.isArray(eventType)) {
|
|
799
|
-
eventTypeList = eventType as string[];
|
|
800
|
-
} else if (typeof eventType === "string") {
|
|
801
|
-
eventTypeList = eventType.split(" ");
|
|
802
|
-
}
|
|
651
|
+
const targetList = [
|
|
652
|
+
{
|
|
653
|
+
target: DOMUtilsContext.windowApi.document,
|
|
654
|
+
eventType: "DOMContentLoaded",
|
|
655
|
+
callback: completed,
|
|
656
|
+
},
|
|
657
|
+
{
|
|
658
|
+
target: DOMUtilsContext.windowApi.window,
|
|
659
|
+
eventType: "load",
|
|
660
|
+
callback: completed,
|
|
661
|
+
},
|
|
662
|
+
];
|
|
663
|
+
/**
|
|
664
|
+
* 添加监听
|
|
665
|
+
*/
|
|
666
|
+
function addDomReadyListener() {
|
|
667
|
+
for (let index = 0; index < targetList.length; index++) {
|
|
668
|
+
const item = targetList[index];
|
|
669
|
+
item.target.addEventListener(item.eventType, item.callback);
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
/**
|
|
673
|
+
* 移除监听
|
|
674
|
+
*/
|
|
675
|
+
function removeDomReadyListener() {
|
|
676
|
+
for (let index = 0; index < targetList.length; index++) {
|
|
677
|
+
const item = targetList[index];
|
|
678
|
+
item.target.removeEventListener(item.eventType, item.callback);
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
if (checkDOMReadyState()) {
|
|
682
|
+
/* 检查document状态 */
|
|
683
|
+
DOMUtilsCommonUtils.setTimeout(callback);
|
|
684
|
+
} else {
|
|
685
|
+
/* 添加监听 */
|
|
686
|
+
addDomReadyListener();
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
/**
|
|
690
|
+
* 主动触发事件
|
|
691
|
+
* @param element 需要触发的元素|元素数组|window
|
|
692
|
+
* @param eventType 需要触发的事件
|
|
693
|
+
* @param details 赋予触发的Event的额外属性,如果是Event类型,那么将自动代替默认new的Event对象
|
|
694
|
+
* @param useDispatchToTriggerEvent 是否使用dispatchEvent来触发事件,默认true
|
|
695
|
+
* @example
|
|
696
|
+
* // 触发元素a.xx的click事件
|
|
697
|
+
* DOMUtils.trigger(document.querySelector("a.xx"),"click")
|
|
698
|
+
* DOMUtils.trigger("a.xx","click")
|
|
699
|
+
* // 触发元素a.xx的click、tap、hover事件
|
|
700
|
+
* DOMUtils.trigger(document.querySelector("a.xx"),"click tap hover")
|
|
701
|
+
* DOMUtils.trigger("a.xx",["click","tap","hover"])
|
|
702
|
+
*/
|
|
703
|
+
trigger(
|
|
704
|
+
element: DOMUtilsTargetElementType | Element | DocumentFragment | any[] | typeof globalThis | Window | Document,
|
|
705
|
+
eventType: string,
|
|
706
|
+
details?: object,
|
|
707
|
+
useDispatchToTriggerEvent?: boolean
|
|
708
|
+
): void;
|
|
709
|
+
/**
|
|
710
|
+
* 主动触发事件
|
|
711
|
+
* @param element 需要触发的元素|元素数组|window
|
|
712
|
+
* @param eventType 需要触发的事件
|
|
713
|
+
* @param details 赋予触发的Event的额外属性,如果是Event类型,那么将自动代替默认new的Event对象
|
|
714
|
+
* @param useDispatchToTriggerEvent 是否使用dispatchEvent来触发事件,默认true
|
|
715
|
+
* @example
|
|
716
|
+
* // 触发元素a.xx的click事件
|
|
717
|
+
* DOMUtils.trigger(document.querySelector("a.xx"),"click")
|
|
718
|
+
* DOMUtils.trigger("a.xx","click")
|
|
719
|
+
* // 触发元素a.xx的click、tap、hover事件
|
|
720
|
+
* DOMUtils.trigger(document.querySelector("a.xx"),"click tap hover")
|
|
721
|
+
* DOMUtils.trigger("a.xx",["click","tap","hover"])
|
|
722
|
+
*/
|
|
723
|
+
trigger(
|
|
724
|
+
element: HTMLElement | string | NodeList | any[] | Window | Document,
|
|
725
|
+
eventType: DOMUtils_EventType | DOMUtils_EventType[],
|
|
726
|
+
details?: object,
|
|
727
|
+
useDispatchToTriggerEvent?: boolean
|
|
728
|
+
): void;
|
|
729
|
+
/**
|
|
730
|
+
* 主动触发事件
|
|
731
|
+
* @param element 需要触发的元素|元素数组|window
|
|
732
|
+
* @param eventType 需要触发的事件
|
|
733
|
+
* @param details 赋予触发的Event的额外属性,如果是Event类型,那么将自动代替默认new的Event对象
|
|
734
|
+
* @param useDispatchToTriggerEvent 是否使用dispatchEvent来触发事件,默认true
|
|
735
|
+
* @example
|
|
736
|
+
* // 触发元素a.xx的click事件
|
|
737
|
+
* DOMUtils.trigger(document.querySelector("a.xx"),"click")
|
|
738
|
+
* DOMUtils.trigger("a.xx","click")
|
|
739
|
+
* // 触发元素a.xx的click、tap、hover事件
|
|
740
|
+
* DOMUtils.trigger(document.querySelector("a.xx"),"click tap hover")
|
|
741
|
+
* DOMUtils.trigger("a.xx",["click","tap","hover"])
|
|
742
|
+
*/
|
|
743
|
+
trigger(
|
|
744
|
+
element: HTMLElement | string | NodeList | any[] | Window | Document,
|
|
745
|
+
eventType: DOMUtils_EventType | DOMUtils_EventType[] | string,
|
|
746
|
+
details?: object,
|
|
747
|
+
useDispatchToTriggerEvent: boolean = true
|
|
748
|
+
) {
|
|
749
|
+
const DOMUtilsContext = this;
|
|
750
|
+
if (typeof element === "string") {
|
|
751
|
+
element = DOMUtilsContext.selectorAll(element);
|
|
752
|
+
}
|
|
753
|
+
if (element == null) {
|
|
754
|
+
return;
|
|
755
|
+
}
|
|
756
|
+
let elementList = [];
|
|
757
|
+
if (element instanceof NodeList || Array.isArray(element)) {
|
|
758
|
+
element = element as HTMLElement[];
|
|
759
|
+
elementList = [...element];
|
|
760
|
+
} else {
|
|
761
|
+
elementList = [element];
|
|
762
|
+
}
|
|
763
|
+
let eventTypeList: string[] = [];
|
|
764
|
+
if (Array.isArray(eventType)) {
|
|
765
|
+
eventTypeList = eventType as string[];
|
|
766
|
+
} else if (typeof eventType === "string") {
|
|
767
|
+
eventTypeList = eventType.split(" ");
|
|
768
|
+
}
|
|
803
769
|
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
770
|
+
elementList.forEach((elementItem) => {
|
|
771
|
+
/* 获取对象上的事件 */
|
|
772
|
+
const events = elementItem[DOMUtilsData.SymbolEvents] || {};
|
|
773
|
+
eventTypeList.forEach((_eventType_) => {
|
|
774
|
+
let event: Event = null as any;
|
|
775
|
+
if (details && details instanceof Event) {
|
|
776
|
+
event = details;
|
|
777
|
+
} else {
|
|
778
|
+
event = new Event(_eventType_);
|
|
779
|
+
if (details) {
|
|
780
|
+
Object.keys(details).forEach((keyName) => {
|
|
781
|
+
(event as any)[keyName] = (details as any)[keyName];
|
|
782
|
+
});
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
if (useDispatchToTriggerEvent == false && _eventType_ in events) {
|
|
786
|
+
events[_eventType_].forEach((eventsItem: any) => {
|
|
787
|
+
eventsItem.callback(event);
|
|
788
|
+
});
|
|
789
|
+
} else {
|
|
790
|
+
elementItem.dispatchEvent(event);
|
|
791
|
+
}
|
|
792
|
+
});
|
|
793
|
+
});
|
|
794
|
+
}
|
|
829
795
|
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
796
|
+
/**
|
|
797
|
+
* 绑定或触发元素的click事件
|
|
798
|
+
* @param element 目标元素
|
|
799
|
+
* @param handler (可选)事件处理函数
|
|
800
|
+
* @param details (可选)赋予触发的Event的额外属性
|
|
801
|
+
* @param useDispatchToTriggerEvent (可选)是否使用dispatchEvent来触发事件,默认true
|
|
802
|
+
* @example
|
|
803
|
+
* // 触发元素a.xx的click事件
|
|
804
|
+
* DOMUtils.click(document.querySelector("a.xx"))
|
|
805
|
+
* DOMUtils.click("a.xx")
|
|
806
|
+
* DOMUtils.click("a.xx",function(){
|
|
807
|
+
* console.log("触发click事件成功")
|
|
808
|
+
* })
|
|
809
|
+
* */
|
|
810
|
+
click(
|
|
811
|
+
element: DOMUtilsTargetElementType | Element | DocumentFragment | typeof globalThis | Window,
|
|
812
|
+
handler?: (this: HTMLElement, event: DOMUtils_Event["click"]) => void,
|
|
813
|
+
details?: any,
|
|
814
|
+
useDispatchToTriggerEvent?: boolean
|
|
815
|
+
) {
|
|
816
|
+
const DOMUtilsContext = this;
|
|
817
|
+
if (typeof element === "string") {
|
|
818
|
+
element = DOMUtilsContext.selectorAll(element);
|
|
819
|
+
}
|
|
820
|
+
if (element == null) {
|
|
821
|
+
return;
|
|
822
|
+
}
|
|
823
|
+
if (DOMUtilsCommonUtils.isNodeList(element)) {
|
|
824
|
+
// 设置
|
|
825
|
+
element.forEach(($ele) => {
|
|
826
|
+
DOMUtilsContext.click($ele as HTMLElement, handler, details, useDispatchToTriggerEvent);
|
|
827
|
+
});
|
|
828
|
+
return;
|
|
829
|
+
}
|
|
830
|
+
if (handler == null) {
|
|
831
|
+
DOMUtilsContext.trigger(element, "click", details, useDispatchToTriggerEvent);
|
|
832
|
+
} else {
|
|
833
|
+
DOMUtilsContext.on(element, "click", null, handler);
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
/**
|
|
837
|
+
* 绑定或触发元素的blur事件
|
|
838
|
+
* @param element 目标元素
|
|
839
|
+
* @param handler (可选)事件处理函数
|
|
840
|
+
* @param details (可选)赋予触发的Event的额外属性
|
|
841
|
+
* @param useDispatchToTriggerEvent (可选)是否使用dispatchEvent来触发事件,默认true
|
|
842
|
+
* @example
|
|
843
|
+
* // 触发元素a.xx的blur事件
|
|
844
|
+
* DOMUtils.blur(document.querySelector("a.xx"))
|
|
845
|
+
* DOMUtils.blur("a.xx")
|
|
846
|
+
* DOMUtils.blur("a.xx",function(){
|
|
847
|
+
* console.log("触发blur事件成功")
|
|
848
|
+
* })
|
|
849
|
+
* */
|
|
850
|
+
blur(
|
|
851
|
+
element: DOMUtilsTargetElementType | Element | DocumentFragment | typeof globalThis | Window,
|
|
852
|
+
handler?: (this: HTMLElement, event: DOMUtils_Event["blur"]) => void,
|
|
853
|
+
details?: object,
|
|
854
|
+
useDispatchToTriggerEvent?: boolean
|
|
855
|
+
) {
|
|
856
|
+
const DOMUtilsContext = this;
|
|
857
|
+
if (typeof element === "string") {
|
|
858
|
+
element = DOMUtilsContext.selectorAll(element);
|
|
859
|
+
}
|
|
860
|
+
if (element == null) {
|
|
861
|
+
return;
|
|
862
|
+
}
|
|
863
|
+
if (DOMUtilsCommonUtils.isNodeList(element)) {
|
|
864
|
+
// 设置
|
|
865
|
+
element.forEach(($ele) => {
|
|
866
|
+
DOMUtilsContext.focus($ele as HTMLElement, handler, details, useDispatchToTriggerEvent);
|
|
867
|
+
});
|
|
868
|
+
return;
|
|
869
|
+
}
|
|
870
|
+
if (handler === null) {
|
|
871
|
+
DOMUtilsContext.trigger(element, "blur", details, useDispatchToTriggerEvent);
|
|
872
|
+
} else {
|
|
873
|
+
DOMUtilsContext.on(element, "blur", null, handler as (event: Event) => void);
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
/**
|
|
877
|
+
* 绑定或触发元素的focus事件
|
|
878
|
+
* @param element 目标元素
|
|
879
|
+
* @param handler (可选)事件处理函数
|
|
880
|
+
* @param details (可选)赋予触发的Event的额外属性
|
|
881
|
+
* @param useDispatchToTriggerEvent (可选)是否使用dispatchEvent来触发事件,默认true
|
|
882
|
+
* @example
|
|
883
|
+
* // 触发元素a.xx的focus事件
|
|
884
|
+
* DOMUtils.focus(document.querySelector("a.xx"))
|
|
885
|
+
* DOMUtils.focus("a.xx")
|
|
886
|
+
* DOMUtils.focus("a.xx",function(){
|
|
887
|
+
* console.log("触发focus事件成功")
|
|
888
|
+
* })
|
|
889
|
+
* */
|
|
890
|
+
focus(
|
|
891
|
+
element: DOMUtilsTargetElementType | Element | DocumentFragment | typeof globalThis | Window,
|
|
892
|
+
handler?: (this: HTMLElement, event: DOMUtils_Event["focus"]) => void,
|
|
893
|
+
details?: object,
|
|
894
|
+
useDispatchToTriggerEvent?: boolean
|
|
895
|
+
) {
|
|
896
|
+
const DOMUtilsContext = this;
|
|
897
|
+
if (typeof element === "string") {
|
|
898
|
+
element = DOMUtilsContext.selectorAll(element);
|
|
899
|
+
}
|
|
900
|
+
if (element == null) {
|
|
901
|
+
return;
|
|
902
|
+
}
|
|
903
|
+
if (DOMUtilsCommonUtils.isNodeList(element)) {
|
|
904
|
+
// 设置
|
|
905
|
+
element.forEach(($ele) => {
|
|
906
|
+
DOMUtilsContext.focus($ele as HTMLElement, handler, details, useDispatchToTriggerEvent);
|
|
907
|
+
});
|
|
908
|
+
return;
|
|
909
|
+
}
|
|
910
|
+
if (handler == null) {
|
|
911
|
+
DOMUtilsContext.trigger(element, "focus", details, useDispatchToTriggerEvent);
|
|
912
|
+
} else {
|
|
913
|
+
DOMUtilsContext.on(element, "focus", null, handler);
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
/**
|
|
917
|
+
* 当鼠标移入或移出元素时触发事件
|
|
918
|
+
* @param element 当前元素
|
|
919
|
+
* @param handler 事件处理函数
|
|
920
|
+
* @param option 配置
|
|
921
|
+
* @example
|
|
922
|
+
* // 监听a.xx元素的移入或移出
|
|
923
|
+
* DOMUtils.hover(document.querySelector("a.xx"),()=>{
|
|
924
|
+
* console.log("移入/移除");
|
|
925
|
+
* })
|
|
926
|
+
* DOMUtils.hover("a.xx",()=>{
|
|
927
|
+
* console.log("移入/移除");
|
|
928
|
+
* })
|
|
929
|
+
*/
|
|
930
|
+
hover(
|
|
931
|
+
element: DOMUtilsTargetElementType | Element | DocumentFragment | Node,
|
|
932
|
+
handler: (this: HTMLElement, event: DOMUtils_Event["hover"]) => void,
|
|
933
|
+
option?: boolean | DOMUtilsEventListenerOption
|
|
934
|
+
) {
|
|
935
|
+
const DOMUtilsContext = this;
|
|
936
|
+
if (typeof element === "string") {
|
|
937
|
+
element = DOMUtilsContext.selectorAll(element);
|
|
938
|
+
}
|
|
939
|
+
if (element == null) {
|
|
940
|
+
return;
|
|
941
|
+
}
|
|
942
|
+
if (DOMUtilsCommonUtils.isNodeList(element)) {
|
|
943
|
+
// 设置
|
|
944
|
+
element.forEach(($ele) => {
|
|
945
|
+
DOMUtilsContext.hover($ele as HTMLElement, handler, option);
|
|
946
|
+
});
|
|
947
|
+
return;
|
|
948
|
+
}
|
|
949
|
+
DOMUtilsContext.on(element, "mouseenter", null, handler, option);
|
|
950
|
+
DOMUtilsContext.on(element, "mouseleave", null, handler, option);
|
|
951
|
+
}
|
|
952
|
+
/**
|
|
953
|
+
* 当动画结束时触发事件
|
|
954
|
+
* @param element 监听的元素
|
|
955
|
+
* @param handler 触发的回调函数
|
|
956
|
+
* @param option 配置项,这里默认配置once为true
|
|
957
|
+
*/
|
|
958
|
+
animationend(
|
|
959
|
+
element: HTMLElement | string | Element | DocumentFragment,
|
|
960
|
+
handler: (this: HTMLElement, event: DOMUtils_Event["animationend"]) => void,
|
|
961
|
+
option?: boolean | DOMUtilsEventListenerOption
|
|
962
|
+
) {
|
|
963
|
+
const DOMUtilsContext = this;
|
|
964
|
+
if (typeof element === "string") {
|
|
965
|
+
element = DOMUtilsContext.selector(element)!;
|
|
966
|
+
}
|
|
967
|
+
if (element == null) {
|
|
968
|
+
return;
|
|
969
|
+
}
|
|
970
|
+
// if (DOMUtilsCommonUtils.isNodeList(element)) {
|
|
971
|
+
// // 设置
|
|
972
|
+
// element.forEach(($ele) => {
|
|
973
|
+
// DOMUtilsContext.animationend($ele as HTMLElement, handler, option);
|
|
974
|
+
// });
|
|
975
|
+
// return;
|
|
976
|
+
// }
|
|
977
|
+
const defaultOption: DOMUtilsEventListenerOption = {
|
|
978
|
+
once: true,
|
|
979
|
+
};
|
|
980
|
+
Object.assign(defaultOption, option || {});
|
|
981
|
+
const eventNameList = DOMUtilsCommonUtils.getAnimationEndNameList();
|
|
982
|
+
DOMUtilsContext.on(element, eventNameList, null, handler, defaultOption);
|
|
983
|
+
if (!defaultOption.once) {
|
|
984
|
+
return {
|
|
985
|
+
off() {
|
|
986
|
+
DOMUtilsContext.off(element, eventNameList, null, handler, defaultOption);
|
|
987
|
+
},
|
|
988
|
+
};
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
/**
|
|
992
|
+
* 当过渡结束时触发事件
|
|
993
|
+
* @param element 监听的元素
|
|
994
|
+
* @param handler 触发的回调函数
|
|
995
|
+
* @param option 配置项,这里默认配置once为true
|
|
996
|
+
*/
|
|
997
|
+
transitionend(
|
|
998
|
+
element: HTMLElement | string | Element | DocumentFragment,
|
|
999
|
+
handler: (this: HTMLElement, event: DOMUtils_Event["transitionend"]) => void,
|
|
1000
|
+
option?: boolean | DOMUtilsEventListenerOption
|
|
1001
|
+
) {
|
|
1002
|
+
const DOMUtilsContext = this;
|
|
1003
|
+
if (typeof element === "string") {
|
|
1004
|
+
element = DOMUtilsContext.selector(element)!;
|
|
1005
|
+
}
|
|
1006
|
+
if (element == null) {
|
|
1007
|
+
return;
|
|
1008
|
+
}
|
|
1009
|
+
// if (DOMUtilsCommonUtils.isNodeList(element)) {
|
|
1010
|
+
// // 设置
|
|
1011
|
+
// element.forEach(($ele) => {
|
|
1012
|
+
// DOMUtilsContext.transitionend($ele as HTMLElement, handler, option);
|
|
1013
|
+
// });
|
|
1014
|
+
// return;
|
|
1015
|
+
// }
|
|
1016
|
+
const defaultOption: DOMUtilsEventListenerOption = {
|
|
1017
|
+
once: true,
|
|
1018
|
+
};
|
|
1019
|
+
Object.assign(defaultOption, option || {});
|
|
1020
|
+
const eventNameList = DOMUtilsCommonUtils.getTransitionEndNameList();
|
|
1021
|
+
DOMUtilsContext.on(element, eventNameList, null, handler, defaultOption);
|
|
1022
|
+
if (!defaultOption.once) {
|
|
1023
|
+
return {
|
|
1024
|
+
off() {
|
|
1025
|
+
DOMUtilsContext.off(element, eventNameList, null, handler, defaultOption);
|
|
1026
|
+
},
|
|
1027
|
+
};
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
/**
|
|
1031
|
+
* 当按键松开时触发事件
|
|
1032
|
+
* keydown - > keypress - > keyup
|
|
1033
|
+
* @param element 当前元素
|
|
1034
|
+
* @param handler 事件处理函数
|
|
1035
|
+
* @param option 配置
|
|
1036
|
+
* @example
|
|
1037
|
+
* // 监听a.xx元素的按键松开
|
|
1038
|
+
* DOMUtils.keyup(document.querySelector("a.xx"),()=>{
|
|
1039
|
+
* console.log("按键松开");
|
|
1040
|
+
* })
|
|
1041
|
+
* DOMUtils.keyup("a.xx",()=>{
|
|
1042
|
+
* console.log("按键松开");
|
|
1043
|
+
* })
|
|
1044
|
+
*/
|
|
1045
|
+
keyup(
|
|
1046
|
+
element: DOMUtilsTargetElementType | Element | DocumentFragment | Window | Node | typeof globalThis,
|
|
1047
|
+
handler: (this: HTMLElement, event: DOMUtils_Event["keyup"]) => void,
|
|
1048
|
+
option?: boolean | DOMUtilsEventListenerOption
|
|
1049
|
+
) {
|
|
1050
|
+
const DOMUtilsContext = this;
|
|
1051
|
+
if (element == null) {
|
|
1052
|
+
return;
|
|
1053
|
+
}
|
|
1054
|
+
if (typeof element === "string") {
|
|
1055
|
+
element = DOMUtilsContext.selectorAll(element);
|
|
1056
|
+
}
|
|
1057
|
+
if (DOMUtilsCommonUtils.isNodeList(element)) {
|
|
1058
|
+
// 设置
|
|
1059
|
+
element.forEach(($ele) => {
|
|
1060
|
+
DOMUtilsContext.keyup($ele as HTMLElement, handler, option);
|
|
1061
|
+
});
|
|
1062
|
+
return;
|
|
1063
|
+
}
|
|
1064
|
+
DOMUtilsContext.on(element, "keyup", null, handler, option);
|
|
1065
|
+
}
|
|
1066
|
+
/**
|
|
1067
|
+
* 当按键按下时触发事件
|
|
1068
|
+
* keydown - > keypress - > keyup
|
|
1069
|
+
* @param element 目标
|
|
1070
|
+
* @param handler 事件处理函数
|
|
1071
|
+
* @param option 配置
|
|
1072
|
+
* @example
|
|
1073
|
+
* // 监听a.xx元素的按键按下
|
|
1074
|
+
* DOMUtils.keydown(document.querySelector("a.xx"),()=>{
|
|
1075
|
+
* console.log("按键按下");
|
|
1076
|
+
* })
|
|
1077
|
+
* DOMUtils.keydown("a.xx",()=>{
|
|
1078
|
+
* console.log("按键按下");
|
|
1079
|
+
* })
|
|
1080
|
+
*/
|
|
1081
|
+
keydown(
|
|
1082
|
+
element: DOMUtilsTargetElementType | Element | DocumentFragment | Window | Node | typeof globalThis,
|
|
1083
|
+
handler: (this: HTMLElement, event: DOMUtils_Event["keydown"]) => void,
|
|
1084
|
+
option?: boolean | DOMUtilsEventListenerOption
|
|
1085
|
+
) {
|
|
1086
|
+
const DOMUtilsContext = this;
|
|
1087
|
+
if (element == null) {
|
|
1088
|
+
return;
|
|
1089
|
+
}
|
|
1090
|
+
if (typeof element === "string") {
|
|
1091
|
+
element = DOMUtilsContext.selectorAll(element);
|
|
1092
|
+
}
|
|
1093
|
+
if (DOMUtilsCommonUtils.isNodeList(element)) {
|
|
1094
|
+
// 设置
|
|
1095
|
+
element.forEach(($ele) => {
|
|
1096
|
+
DOMUtilsContext.keydown($ele as HTMLElement, handler, option);
|
|
1097
|
+
});
|
|
1098
|
+
return;
|
|
1099
|
+
}
|
|
1100
|
+
DOMUtilsContext.on(element, "keydown", null, handler, option);
|
|
1101
|
+
}
|
|
1102
|
+
/**
|
|
1103
|
+
* 当按键按下时触发事件
|
|
1104
|
+
* keydown - > keypress - > keyup
|
|
1105
|
+
* @param element 目标
|
|
1106
|
+
* @param handler 事件处理函数
|
|
1107
|
+
* @param option 配置
|
|
1108
|
+
* @example
|
|
1109
|
+
* // 监听a.xx元素的按键按下
|
|
1110
|
+
* DOMUtils.keypress(document.querySelector("a.xx"),()=>{
|
|
1111
|
+
* console.log("按键按下");
|
|
1112
|
+
* })
|
|
1113
|
+
* DOMUtils.keypress("a.xx",()=>{
|
|
1114
|
+
* console.log("按键按下");
|
|
1115
|
+
* })
|
|
1116
|
+
*/
|
|
1117
|
+
keypress(
|
|
1118
|
+
element: DOMUtilsTargetElementType | Element | DocumentFragment | Window | Node | typeof globalThis,
|
|
1119
|
+
handler: (this: HTMLElement, event: DOMUtils_Event["keypress"]) => void,
|
|
1120
|
+
option?: boolean | DOMUtilsEventListenerOption
|
|
1121
|
+
) {
|
|
1122
|
+
const DOMUtilsContext = this;
|
|
1123
|
+
if (element == null) {
|
|
1124
|
+
return;
|
|
1125
|
+
}
|
|
1126
|
+
if (typeof element === "string") {
|
|
1127
|
+
element = DOMUtilsContext.selectorAll(element);
|
|
1128
|
+
}
|
|
1129
|
+
if (DOMUtilsCommonUtils.isNodeList(element)) {
|
|
1130
|
+
// 设置
|
|
1131
|
+
element.forEach(($ele) => {
|
|
1132
|
+
DOMUtilsContext.keypress($ele as HTMLElement, handler, option);
|
|
1133
|
+
});
|
|
1134
|
+
return;
|
|
1135
|
+
}
|
|
1136
|
+
DOMUtilsContext.on(element, "keypress", null, handler, option);
|
|
1137
|
+
}
|
|
1138
|
+
/**
|
|
1173
1139
|
* 监听某个元素键盘按键事件或window全局按键事件
|
|
1174
1140
|
* 按下有值的键时触发,按下Ctrl\Alt\Shift\Meta是无值键。按下先触发keydown事件,再触发keypress事件。
|
|
1175
1141
|
* @param element 需要监听的对象,可以是全局Window或者某个元素
|
|
@@ -1232,311 +1198,293 @@ export class DOMUtilsEvent {
|
|
|
1232
1198
|
搜索 170
|
|
1233
1199
|
收藏 171
|
|
1234
1200
|
**/
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
*/
|
|
1408
|
-
matches($el: HTMLElement | Element | null | undefined, selector: string): boolean {
|
|
1409
|
-
selector = selector.trim();
|
|
1410
|
-
if ($el == null) {
|
|
1411
|
-
return false;
|
|
1412
|
-
}
|
|
1201
|
+
listenKeyboard(
|
|
1202
|
+
element: DOMUtilsTargetElementType | Element | DocumentFragment | Window | Node | typeof globalThis,
|
|
1203
|
+
eventName: "keyup" | "keypress" | "keydown" = "keypress",
|
|
1204
|
+
callback: (keyName: string, keyValue: number, otherCodeList: string[], event: KeyboardEvent) => void,
|
|
1205
|
+
options?: DOMUtilsEventListenerOption | boolean
|
|
1206
|
+
): {
|
|
1207
|
+
removeListen(): void;
|
|
1208
|
+
} {
|
|
1209
|
+
const DOMUtilsContext = this;
|
|
1210
|
+
if (typeof element === "string") {
|
|
1211
|
+
element = DOMUtilsContext.selectorAll(element);
|
|
1212
|
+
}
|
|
1213
|
+
const keyboardEventCallBack = function (event: KeyboardEvent) {
|
|
1214
|
+
/** 键名 */
|
|
1215
|
+
const keyName = event.key || event.code;
|
|
1216
|
+
/** 键值 */
|
|
1217
|
+
const keyValue = event.charCode || event.keyCode || event.which;
|
|
1218
|
+
/** 组合键列表 */
|
|
1219
|
+
const otherCodeList: string[] = [];
|
|
1220
|
+
if (event.ctrlKey) {
|
|
1221
|
+
otherCodeList.push("ctrl");
|
|
1222
|
+
}
|
|
1223
|
+
if (event.altKey) {
|
|
1224
|
+
otherCodeList.push("alt");
|
|
1225
|
+
}
|
|
1226
|
+
if (event.metaKey) {
|
|
1227
|
+
otherCodeList.push("meta");
|
|
1228
|
+
}
|
|
1229
|
+
if (event.shiftKey) {
|
|
1230
|
+
otherCodeList.push("shift");
|
|
1231
|
+
}
|
|
1232
|
+
if (typeof callback === "function") {
|
|
1233
|
+
callback(keyName, keyValue, otherCodeList, event);
|
|
1234
|
+
}
|
|
1235
|
+
};
|
|
1236
|
+
DOMUtilsContext.on(element, eventName, keyboardEventCallBack, options);
|
|
1237
|
+
return {
|
|
1238
|
+
removeListen: () => {
|
|
1239
|
+
DOMUtilsContext.off(element, eventName, keyboardEventCallBack, options);
|
|
1240
|
+
},
|
|
1241
|
+
};
|
|
1242
|
+
}
|
|
1243
|
+
/**
|
|
1244
|
+
* 选择器,可使用以下的额外语法
|
|
1245
|
+
*
|
|
1246
|
+
* + :contains([text]) 作用: 找到包含指定文本内容的指定元素
|
|
1247
|
+
* + :empty 作用:找到既没有文本内容也没有子元素的指定元素
|
|
1248
|
+
* + :regexp([text]) 作用: 找到符合正则表达式的内容的指定元素
|
|
1249
|
+
* @param selector 选择器
|
|
1250
|
+
* @param parent 指定父元素
|
|
1251
|
+
* @example
|
|
1252
|
+
* DOMUtils.selector("div:contains('测试')")
|
|
1253
|
+
* > div.xxx
|
|
1254
|
+
* @example
|
|
1255
|
+
* DOMUtils.selector("div:empty")
|
|
1256
|
+
* > div.xxx
|
|
1257
|
+
* @example
|
|
1258
|
+
* DOMUtils.selector("div:regexp('^xxxx$')")
|
|
1259
|
+
* > div.xxx
|
|
1260
|
+
*/
|
|
1261
|
+
selector<K extends keyof HTMLElementTagNameMap>(
|
|
1262
|
+
selector: K,
|
|
1263
|
+
parent?: Element | Document | DocumentFragment | ShadowRoot
|
|
1264
|
+
): HTMLElementTagNameMap[K] | undefined;
|
|
1265
|
+
selector<E extends Element = HTMLElement>(
|
|
1266
|
+
selector: string,
|
|
1267
|
+
parent?: Element | Document | DocumentFragment | ShadowRoot
|
|
1268
|
+
): E | undefined;
|
|
1269
|
+
selector<E extends Element = HTMLElement>(
|
|
1270
|
+
selector: string,
|
|
1271
|
+
parent?: Element | Document | DocumentFragment | ShadowRoot
|
|
1272
|
+
) {
|
|
1273
|
+
return this.selectorAll<E>(selector, parent)[0];
|
|
1274
|
+
}
|
|
1275
|
+
/**
|
|
1276
|
+
* 选择器,可使用以下的额外语法
|
|
1277
|
+
*
|
|
1278
|
+
* + :contains([text]) 作用: 找到包含指定文本内容的指定元素
|
|
1279
|
+
* + :empty 作用:找到既没有文本内容也没有子元素的指定元素
|
|
1280
|
+
* + :regexp([text]) 作用: 找到符合正则表达式的内容的指定元素
|
|
1281
|
+
* @param selector 选择器
|
|
1282
|
+
* @param parent 指定父元素
|
|
1283
|
+
* @example
|
|
1284
|
+
* DOMUtils.selectorAll("div:contains('测试')")
|
|
1285
|
+
* > [div.xxx]
|
|
1286
|
+
* @example
|
|
1287
|
+
* DOMUtils.selectorAll("div:empty")
|
|
1288
|
+
* > [div.xxx]
|
|
1289
|
+
* @example
|
|
1290
|
+
* DOMUtils.selectorAll("div:regexp('^xxxx$')")
|
|
1291
|
+
* > [div.xxx]
|
|
1292
|
+
* @example
|
|
1293
|
+
* DOMUtils.selectorAll("div:regexp(/^xxx/ig)")
|
|
1294
|
+
* > [div.xxx]
|
|
1295
|
+
*/
|
|
1296
|
+
selectorAll<K extends keyof HTMLElementTagNameMap>(
|
|
1297
|
+
selector: K,
|
|
1298
|
+
parent?: Element | Document | DocumentFragment | ShadowRoot
|
|
1299
|
+
): HTMLElementTagNameMap[K][];
|
|
1300
|
+
selectorAll<E extends Element = HTMLElement>(
|
|
1301
|
+
selector: string,
|
|
1302
|
+
parent?: Element | Document | DocumentFragment | ShadowRoot
|
|
1303
|
+
): E[];
|
|
1304
|
+
selectorAll<E extends Element = HTMLElement>(
|
|
1305
|
+
selector: string,
|
|
1306
|
+
parent?: Element | Document | DocumentFragment | ShadowRoot
|
|
1307
|
+
) {
|
|
1308
|
+
const context = this;
|
|
1309
|
+
parent = parent || context.windowApi.document;
|
|
1310
|
+
selector = selector.trim();
|
|
1311
|
+
if (selector.match(/[^\s]{1}:empty$/gi)) {
|
|
1312
|
+
// empty 语法
|
|
1313
|
+
selector = selector.replace(/:empty$/gi, "");
|
|
1314
|
+
return Array.from(parent.querySelectorAll<E>(selector)).filter(($ele) => {
|
|
1315
|
+
return $ele?.innerHTML?.trim() === "";
|
|
1316
|
+
});
|
|
1317
|
+
} else if (selector.match(/[^\s]{1}:contains\("(.*)"\)$/i) || selector.match(/[^\s]{1}:contains\('(.*)'\)$/i)) {
|
|
1318
|
+
// contains 语法
|
|
1319
|
+
const textMatch = selector.match(/:contains\(("|')(.*)("|')\)$/i);
|
|
1320
|
+
const text = textMatch![2];
|
|
1321
|
+
selector = selector.replace(/:contains\(("|')(.*)("|')\)$/gi, "");
|
|
1322
|
+
return Array.from(parent.querySelectorAll<E>(selector)).filter(($ele) => {
|
|
1323
|
+
// @ts-ignore
|
|
1324
|
+
return ($ele?.textContent || $ele?.innerText)?.includes(text);
|
|
1325
|
+
});
|
|
1326
|
+
} else if (selector.match(/[^\s]{1}:regexp\("(.*)"\)$/i) || selector.match(/[^\s]{1}:regexp\('(.*)'\)$/i)) {
|
|
1327
|
+
// regexp 语法
|
|
1328
|
+
const textMatch = selector.match(/:regexp\(("|')(.*)("|')\)$/i);
|
|
1329
|
+
let pattern = textMatch![2];
|
|
1330
|
+
const flagMatch = pattern.match(/("|'),[\s]*("|')([igm]{0,3})$/i);
|
|
1331
|
+
let flags = "";
|
|
1332
|
+
if (flagMatch) {
|
|
1333
|
+
pattern = pattern.replace(/("|'),[\s]*("|')([igm]{0,3})$/gi, "");
|
|
1334
|
+
flags = flagMatch[3];
|
|
1335
|
+
}
|
|
1336
|
+
const regexp = new RegExp(pattern, flags);
|
|
1337
|
+
selector = selector.replace(/:regexp\(("|')(.*)("|')\)$/gi, "");
|
|
1338
|
+
return Array.from(parent.querySelectorAll<E>(selector)).filter(($ele) => {
|
|
1339
|
+
// @ts-ignore
|
|
1340
|
+
return Boolean(($ele?.textContent || $ele?.innerText)?.match(regexp));
|
|
1341
|
+
});
|
|
1342
|
+
} else {
|
|
1343
|
+
// 普通语法
|
|
1344
|
+
return Array.from(parent.querySelectorAll<E>(selector));
|
|
1345
|
+
}
|
|
1346
|
+
}
|
|
1347
|
+
/**
|
|
1348
|
+
* 匹配元素,可使用以下的额外语法
|
|
1349
|
+
*
|
|
1350
|
+
* + :contains([text]) 作用: 找到包含指定文本内容的指定元素
|
|
1351
|
+
* + :empty 作用:找到既没有文本内容也没有子元素的指定元素
|
|
1352
|
+
* + :regexp([text]) 作用: 找到符合正则表达式的内容的指定元素
|
|
1353
|
+
* @param $el 元素
|
|
1354
|
+
* @param selector 选择器
|
|
1355
|
+
* @example
|
|
1356
|
+
* DOMUtils.matches("div:contains('测试')")
|
|
1357
|
+
* > true
|
|
1358
|
+
* @example
|
|
1359
|
+
* DOMUtils.matches("div:empty")
|
|
1360
|
+
* > true
|
|
1361
|
+
* @example
|
|
1362
|
+
* DOMUtils.matches("div:regexp('^xxxx$')")
|
|
1363
|
+
* > true
|
|
1364
|
+
* @example
|
|
1365
|
+
* DOMUtils.matches("div:regexp(/^xxx/ig)")
|
|
1366
|
+
* > false
|
|
1367
|
+
*/
|
|
1368
|
+
matches($el: HTMLElement | Element | null | undefined, selector: string): boolean {
|
|
1369
|
+
selector = selector.trim();
|
|
1370
|
+
if ($el == null) {
|
|
1371
|
+
return false;
|
|
1372
|
+
}
|
|
1413
1373
|
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
$el: HTMLElement | Element,
|
|
1481
|
-
selector: string
|
|
1482
|
-
): HTMLElementTagNameMap[K] | null;
|
|
1483
|
-
closest<E extends Element = Element>($el: HTMLElement | Element, selector: string): E | null;
|
|
1484
|
-
closest<E extends Element = Element>($el: HTMLElement | Element, selector: string): E | null {
|
|
1485
|
-
selector = selector.trim();
|
|
1374
|
+
if (selector.match(/[^\s]{1}:empty$/gi)) {
|
|
1375
|
+
// empty 语法
|
|
1376
|
+
selector = selector.replace(/:empty$/gi, "");
|
|
1377
|
+
return $el.matches(selector) && $el?.innerHTML?.trim() === "";
|
|
1378
|
+
} else if (selector.match(/[^\s]{1}:contains\("(.*)"\)$/i) || selector.match(/[^\s]{1}:contains\('(.*)'\)$/i)) {
|
|
1379
|
+
// contains 语法
|
|
1380
|
+
const textMatch = selector.match(/:contains\(("|')(.*)("|')\)$/i);
|
|
1381
|
+
const text = textMatch![2];
|
|
1382
|
+
selector = selector.replace(/:contains\(("|')(.*)("|')\)$/gi, "");
|
|
1383
|
+
// @ts-ignore
|
|
1384
|
+
let content = $el?.textContent || $el?.innerText;
|
|
1385
|
+
if (typeof content !== "string") {
|
|
1386
|
+
content = "";
|
|
1387
|
+
}
|
|
1388
|
+
return $el.matches(selector) && content?.includes(text);
|
|
1389
|
+
} else if (selector.match(/[^\s]{1}:regexp\("(.*)"\)$/i) || selector.match(/[^\s]{1}:regexp\('(.*)'\)$/i)) {
|
|
1390
|
+
// regexp 语法
|
|
1391
|
+
const textMatch = selector.match(/:regexp\(("|')(.*)("|')\)$/i);
|
|
1392
|
+
let pattern = textMatch![2];
|
|
1393
|
+
const flagMatch = pattern.match(/("|'),[\s]*("|')([igm]{0,3})$/i);
|
|
1394
|
+
let flags = "";
|
|
1395
|
+
if (flagMatch) {
|
|
1396
|
+
pattern = pattern.replace(/("|'),[\s]*("|')([igm]{0,3})$/gi, "");
|
|
1397
|
+
flags = flagMatch[3];
|
|
1398
|
+
}
|
|
1399
|
+
const regexp = new RegExp(pattern, flags);
|
|
1400
|
+
selector = selector.replace(/:regexp\(("|')(.*)("|')\)$/gi, "");
|
|
1401
|
+
// @ts-ignore
|
|
1402
|
+
let content = $el?.textContent || $el?.innerText;
|
|
1403
|
+
if (typeof content !== "string") {
|
|
1404
|
+
content = "";
|
|
1405
|
+
}
|
|
1406
|
+
return $el.matches(selector) && Boolean(content?.match(regexp));
|
|
1407
|
+
} else {
|
|
1408
|
+
// 普通语法
|
|
1409
|
+
return $el.matches(selector);
|
|
1410
|
+
}
|
|
1411
|
+
}
|
|
1412
|
+
/**
|
|
1413
|
+
* 根据选择器获取上层元素,可使用以下的额外语法
|
|
1414
|
+
*
|
|
1415
|
+
* + :contains([text]) 作用: 找到包含指定文本内容的指定元素
|
|
1416
|
+
* + :empty 作用:找到既没有文本内容也没有子元素的指定元素
|
|
1417
|
+
* + :regexp([text]) 作用: 找到符合正则表达式的内容的指定元素
|
|
1418
|
+
* @param $el 元素
|
|
1419
|
+
* @param selector 选择器
|
|
1420
|
+
* @example
|
|
1421
|
+
* DOMUtils.closest("div:contains('测试')")
|
|
1422
|
+
* > div.xxx
|
|
1423
|
+
* @example
|
|
1424
|
+
* DOMUtils.closest("div:empty")
|
|
1425
|
+
* > div.xxx
|
|
1426
|
+
* @example
|
|
1427
|
+
* DOMUtils.closest("div:regexp('^xxxx$')")
|
|
1428
|
+
* > div.xxxx
|
|
1429
|
+
* @example
|
|
1430
|
+
* DOMUtils.closest("div:regexp(/^xxx/ig)")
|
|
1431
|
+
* > null
|
|
1432
|
+
*/
|
|
1433
|
+
closest<K extends keyof HTMLElementTagNameMap>(
|
|
1434
|
+
$el: HTMLElement | Element,
|
|
1435
|
+
selector: string
|
|
1436
|
+
): HTMLElementTagNameMap[K] | null;
|
|
1437
|
+
closest<E extends Element = Element>($el: HTMLElement | Element, selector: string): E | null;
|
|
1438
|
+
closest<E extends Element = Element>($el: HTMLElement | Element, selector: string): E | null {
|
|
1439
|
+
selector = selector.trim();
|
|
1486
1440
|
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
} else {
|
|
1537
|
-
// 普通语法
|
|
1538
|
-
let $closest = $el?.closest<E>(selector);
|
|
1539
|
-
return $closest;
|
|
1540
|
-
}
|
|
1541
|
-
}
|
|
1441
|
+
if (selector.match(/[^\s]{1}:empty$/gi)) {
|
|
1442
|
+
// empty 语法
|
|
1443
|
+
selector = selector.replace(/:empty$/gi, "");
|
|
1444
|
+
const $closest = $el?.closest<E>(selector);
|
|
1445
|
+
if ($closest && $closest?.innerHTML?.trim() === "") {
|
|
1446
|
+
return $closest;
|
|
1447
|
+
}
|
|
1448
|
+
return null;
|
|
1449
|
+
} else if (selector.match(/[^\s]{1}:contains\("(.*)"\)$/i) || selector.match(/[^\s]{1}:contains\('(.*)'\)$/i)) {
|
|
1450
|
+
// contains 语法
|
|
1451
|
+
const textMatch = selector.match(/:contains\(("|')(.*)("|')\)$/i);
|
|
1452
|
+
const text = textMatch![2];
|
|
1453
|
+
selector = selector.replace(/:contains\(("|')(.*)("|')\)$/gi, "");
|
|
1454
|
+
const $closest = $el?.closest<E>(selector);
|
|
1455
|
+
if ($closest) {
|
|
1456
|
+
// @ts-ignore
|
|
1457
|
+
const content = $el?.textContent || $el?.innerText;
|
|
1458
|
+
if (typeof content === "string" && content.includes(text)) {
|
|
1459
|
+
return $closest;
|
|
1460
|
+
}
|
|
1461
|
+
}
|
|
1462
|
+
return null;
|
|
1463
|
+
} else if (selector.match(/[^\s]{1}:regexp\("(.*)"\)$/i) || selector.match(/[^\s]{1}:regexp\('(.*)'\)$/i)) {
|
|
1464
|
+
// regexp 语法
|
|
1465
|
+
const textMatch = selector.match(/:regexp\(("|')(.*)("|')\)$/i);
|
|
1466
|
+
let pattern = textMatch![2];
|
|
1467
|
+
const flagMatch = pattern.match(/("|'),[\s]*("|')([igm]{0,3})$/i);
|
|
1468
|
+
let flags = "";
|
|
1469
|
+
if (flagMatch) {
|
|
1470
|
+
pattern = pattern.replace(/("|'),[\s]*("|')([igm]{0,3})$/gi, "");
|
|
1471
|
+
flags = flagMatch[3];
|
|
1472
|
+
}
|
|
1473
|
+
const regexp = new RegExp(pattern, flags);
|
|
1474
|
+
selector = selector.replace(/:regexp\(("|')(.*)("|')\)$/gi, "");
|
|
1475
|
+
const $closest = $el?.closest<E>(selector);
|
|
1476
|
+
if ($closest) {
|
|
1477
|
+
// @ts-ignore
|
|
1478
|
+
const content = $el?.textContent || $el?.innerText;
|
|
1479
|
+
if (typeof content === "string" && content.match(regexp)) {
|
|
1480
|
+
return $closest;
|
|
1481
|
+
}
|
|
1482
|
+
}
|
|
1483
|
+
return null;
|
|
1484
|
+
} else {
|
|
1485
|
+
// 普通语法
|
|
1486
|
+
const $closest = $el?.closest<E>(selector);
|
|
1487
|
+
return $closest;
|
|
1488
|
+
}
|
|
1489
|
+
}
|
|
1542
1490
|
}
|