@whitesev/domutils 1.1.5 → 1.2.0

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.
@@ -0,0 +1,1237 @@
1
+ import { DOMUtilsCommonUtils } from "./DOMUtilsCommonUtils";
2
+ import { DOMUtilsCore } from "./DOMUtilsCore";
3
+ import { DOMUtilsData } from "./DOMUtilsData";
4
+ import { OriginPrototype } from "./DOMUtilsOriginPrototype";
5
+
6
+ export type DOMUtilsEventObject<T extends Node> = Event & {
7
+ target: T;
8
+ };
9
+
10
+ export declare type DOMUtilsCreateElementAttributesMap = {
11
+ style?: string;
12
+ id?: string;
13
+ class?: string;
14
+ "data-"?: string;
15
+ type?: string;
16
+ [key: string]: any;
17
+ };
18
+ /**
19
+ * 鼠标事件
20
+ * + https://blog.csdn.net/weixin_68658847/article/details/126939879
21
+ */
22
+
23
+ export interface DOMUtils_MouseEvent {
24
+ click: MouseEvent | PointerEvent;
25
+ contextmenu: MouseEvent | PointerEvent;
26
+ dblclick: MouseEvent | PointerEvent;
27
+ mousedown: MouseEvent | PointerEvent;
28
+ mouseenter: MouseEvent | PointerEvent;
29
+ mouseleave: MouseEvent | PointerEvent;
30
+ mousemove: MouseEvent | PointerEvent;
31
+ mouseover: MouseEvent | PointerEvent;
32
+ mouseout: MouseEvent | PointerEvent;
33
+ mouseup: MouseEvent | PointerEvent;
34
+ hover: MouseEvent;
35
+ }
36
+ export type DOMUtils_MouseEventType = keyof DOMUtils_MouseEvent;
37
+ /**
38
+ * 鼠标事件
39
+ */
40
+ export interface DOMUtils_KeyboardEvent {
41
+ keydown: KeyboardEvent;
42
+ keypress: KeyboardEvent;
43
+ keyup: KeyboardEvent;
44
+ }
45
+ export type DOMUtils_KeyboardEventType = keyof DOMUtils_KeyboardEvent;
46
+ /**
47
+ * 框架/对象事件
48
+ */
49
+ export interface DOMUtils_Frame_Object_Event {
50
+ abort: Event;
51
+ beforeunload: Event;
52
+ error: Event;
53
+ hashchange: Event;
54
+ load: Event;
55
+ pageshow: Event;
56
+ pagehide: Event;
57
+ resize: Event;
58
+ scroll: Event;
59
+ unload: Event;
60
+ }
61
+ export type DOMUtils_Frame_Object_EventType = keyof DOMUtils_Frame_Object_Event;
62
+ /**
63
+ * 表单事件
64
+ */
65
+ export interface DOMUtils_FormEvent {
66
+ blur: Event;
67
+ change: Event;
68
+ focus: Event;
69
+ focusin: Event;
70
+ focusout: Event;
71
+ input: Event;
72
+ reset: Event;
73
+ search: Event;
74
+ }
75
+ export type DOMUtils_FormEventType = keyof DOMUtils_FormEvent;
76
+
77
+ /**
78
+ * 剪贴板事件
79
+ */
80
+ export interface DOMUtils_ClipboardEvent {
81
+ copy: ClipboardEvent;
82
+ cut: ClipboardEvent;
83
+ paste: ClipboardEvent;
84
+ }
85
+ export type DOMUtils_ClipboardEventType = keyof DOMUtils_ClipboardEvent;
86
+
87
+ /**
88
+ * 打印事件
89
+ */
90
+ export interface DOMUtils_PrintEvent {
91
+ afterprint: Event;
92
+ beforeprint: Event;
93
+ }
94
+ export type DOMUtils_PrintEventType = keyof DOMUtils_PrintEvent;
95
+
96
+ /**
97
+ * 拖动事件
98
+ */
99
+ export interface DOMUtils_DragEvent {
100
+ drag: DragEvent;
101
+ dragend: DragEvent;
102
+ dragenter: DragEvent;
103
+ dragleave: DragEvent;
104
+ dragover: DragEvent;
105
+ dragstart: DragEvent;
106
+ drop: DragEvent;
107
+ }
108
+ export type DOMUtils_DragEventType = keyof DOMUtils_DragEvent;
109
+
110
+ /**
111
+ * 多媒体(Media)事件
112
+ */
113
+ export interface DOMUtils_MediaEvent {
114
+ abort: Event;
115
+ canplay: Event;
116
+ canplaythrough: Event;
117
+ durationchange: Event;
118
+ emptied: Event;
119
+ ended: Event;
120
+ error: Event;
121
+ loadeddata: Event;
122
+ loadedmetadata: Event;
123
+ loadstart: Event;
124
+ pause: Event;
125
+ play: Event;
126
+ playing: Event;
127
+ progress: Event;
128
+ ratechange: Event;
129
+ seeked: Event;
130
+ seeking: Event;
131
+ stalled: Event;
132
+ suspend: Event;
133
+ timeupdate: Event;
134
+ volumechange: Event;
135
+ waiting: Event;
136
+ }
137
+ export type DOMUtils_MediaEventType = keyof DOMUtils_MediaEvent;
138
+
139
+ /**
140
+ * 动画事件
141
+ */
142
+ export interface DOMUtils_AnimationEvent {
143
+ animationend: AnimationEvent;
144
+ animationiteration: AnimationEvent;
145
+ animationstart: AnimationEvent;
146
+ }
147
+ export type DOMUtils_AnimationEventType = keyof DOMUtils_AnimationEvent;
148
+
149
+ /**
150
+ * 过渡事件
151
+ */
152
+ export interface DOMUtils_TransitionEvent {
153
+ transitionend: TransitionEvent;
154
+ }
155
+ export type DOMUtils_TransitionEventType = keyof DOMUtils_TransitionEvent;
156
+
157
+ /**
158
+ * 触摸事件
159
+ */
160
+ export interface DOMUtils_TouchEvent {
161
+ touchstart: TouchEvent;
162
+ touchmove: TouchEvent;
163
+ touchend: TouchEvent;
164
+ touchcancel: TouchEvent;
165
+ touchenter: TouchEvent;
166
+ touchleave: TouchEvent;
167
+ }
168
+ export type DOMUtils_TouchEventType = keyof DOMUtils_TouchEvent;
169
+ /**
170
+ * 其它事件
171
+ */
172
+ export interface DOMUtils_OtherEvent {
173
+ message: Event;
174
+ online: Event;
175
+ offline: Event;
176
+ popstate: Event;
177
+ show: Event;
178
+ storage: Event;
179
+ toggle: Event;
180
+ wheel: Event;
181
+ propertychange: Event;
182
+ fullscreenchange: Event;
183
+ DOMContentLoaded: Event;
184
+ }
185
+ export type DOMUtils_OtherEventType = keyof DOMUtils_OtherEvent;
186
+
187
+ /**
188
+ * 全部事件
189
+ */
190
+ export declare type DOMUtils_Event = DOMUtils_MouseEvent &
191
+ DOMUtils_KeyboardEvent &
192
+ DOMUtils_Frame_Object_Event &
193
+ DOMUtils_FormEvent &
194
+ DOMUtils_ClipboardEvent &
195
+ DOMUtils_PrintEvent &
196
+ DOMUtils_DragEvent &
197
+ DOMUtils_MediaEvent &
198
+ DOMUtils_AnimationEvent &
199
+ DOMUtils_TransitionEvent &
200
+ DOMUtils_TouchEvent &
201
+ DOMUtils_OtherEvent;
202
+
203
+ /**
204
+ * 事件类型
205
+ */
206
+ export declare type DOMUtils_EventType = keyof DOMUtils_Event;
207
+
208
+ /**
209
+ * 元素上的events属性
210
+ */
211
+ export declare interface DOMUtilsEventListenerOptionsAttribute {
212
+ /**
213
+ * 自定义的ownCallBack
214
+ */
215
+ callback: () => void;
216
+ /**
217
+ * 属性配置
218
+ */
219
+ option: AddEventListenerOptions;
220
+ /**
221
+ * 用户添加的事件
222
+ */
223
+ originCallBack: () => void;
224
+ /**
225
+ * 子元素选择器
226
+ */
227
+ selector?: string;
228
+ }
229
+
230
+ export declare type DOMUtilsElementEventType =
231
+ | HTMLElement
232
+ | string
233
+ | NodeList
234
+ | (HTMLElement | Window | Document | Element | typeof globalThis)[]
235
+ | Window
236
+ | Document
237
+ | Element
238
+ | null
239
+ | typeof globalThis
240
+ | ShadowRoot
241
+ | EventTarget
242
+ | ChildNode
243
+ | Node;
244
+
245
+ class DOMUtilsEvent {
246
+ /**
247
+ * 绑定事件
248
+ * @param element 需要绑定的元素|元素数组|window
249
+ * @param eventType 需要监听的事件
250
+ * @param callback 绑定事件触发的回调函数
251
+ * @param option
252
+ * + capture 表示事件是否在捕获阶段触发。默认为false,即在冒泡阶段触发
253
+ * + once 表示事件是否只触发一次。默认为false
254
+ * + passive 表示事件监听器是否不会调用preventDefault()。默认为false
255
+ * @example
256
+ * // 监听元素a.xx的click事件
257
+ * DOMUtils.on(document.querySelector("a.xx"),"click",(event)=>{
258
+ * console.log("事件触发",event)
259
+ * })
260
+ * DOMUtils.on("a.xx","click",(event)=>{
261
+ * console.log("事件触发",event)
262
+ * })
263
+ */
264
+ on<T extends DOMUtils_EventType>(
265
+ element: DOMUtilsElementEventType,
266
+ eventType: T | T[],
267
+ callback: (event: DOMUtils_Event[T]) => void,
268
+ option?: boolean | AddEventListenerOptions
269
+ ): void;
270
+ /**
271
+ * 绑定事件
272
+ * @param element 需要绑定的元素|元素数组|window
273
+ * @param eventType 需要监听的事件
274
+ * @param callback 绑定事件触发的回调函数
275
+ * @param option
276
+ * + capture 表示事件是否在捕获阶段触发。默认为false,即在冒泡阶段触发
277
+ * + once 表示事件是否只触发一次。默认为false
278
+ * + passive 表示事件监听器是否不会调用preventDefault()。默认为false
279
+ * @example
280
+ * // 监听元素a.xx的click事件
281
+ * DOMUtils.on(document.querySelector("a.xx"),"click",(event)=>{
282
+ * console.log("事件触发",event)
283
+ * })
284
+ * DOMUtils.on("a.xx","click",(event)=>{
285
+ * console.log("事件触发",event)
286
+ * })
287
+ */
288
+ on<T extends Event>(
289
+ element: DOMUtilsElementEventType,
290
+ eventType: string,
291
+ callback: (event: T) => void,
292
+ option?: boolean | AddEventListenerOptions
293
+ ): void;
294
+ /**
295
+ * 绑定事件
296
+ * @param element 需要绑定的元素|元素数组|window
297
+ * @param eventType 需要监听的事件
298
+ * @param selector 子元素选择器
299
+ * @param callback 绑定事件触发的回调函数
300
+ * @param option
301
+ * + capture 表示事件是否在捕获阶段触发。默认为false,即在冒泡阶段触发
302
+ * + once 表示事件是否只触发一次。默认为false
303
+ * + passive 表示事件监听器是否不会调用preventDefault()。默认为false
304
+ * @example
305
+ * // 监听元素a.xx的click、tap、hover事件
306
+ * DOMUtils.on(document.querySelector("a.xx"),"click tap hover",(event)=>{
307
+ * console.log("事件触发",event)
308
+ * })
309
+ * DOMUtils.on("a.xx",["click","tap","hover"],(event)=>{
310
+ * console.log("事件触发",event)
311
+ * })
312
+ * @example
313
+ * // 监听全局document下的子元素a.xx的click事件
314
+ * DOMUtils.on(document,"click tap hover","a.xx",(event)=>{
315
+ * console.log("事件触发",event)
316
+ * })
317
+ */
318
+ on<T extends DOMUtils_EventType>(
319
+ element: DOMUtilsElementEventType,
320
+ eventType: T | T[],
321
+ selector: string | undefined | null,
322
+ callback: (event: DOMUtils_Event[T]) => void,
323
+ option?: boolean | AddEventListenerOptions
324
+ ): void;
325
+ /**
326
+ * 绑定事件
327
+ * @param element 需要绑定的元素|元素数组|window
328
+ * @param eventType 需要监听的事件
329
+ * @param selector 子元素选择器
330
+ * @param callback 绑定事件触发的回调函数
331
+ * @param option
332
+ * + capture 表示事件是否在捕获阶段触发。默认为false,即在冒泡阶段触发
333
+ * + once 表示事件是否只触发一次。默认为false
334
+ * + passive 表示事件监听器是否不会调用preventDefault()。默认为false
335
+ * @example
336
+ * // 监听元素a.xx的click、tap、hover事件
337
+ * DOMUtils.on(document.querySelector("a.xx"),"click tap hover",(event)=>{
338
+ * console.log("事件触发",event)
339
+ * })
340
+ * DOMUtils.on("a.xx",["click","tap","hover"],(event)=>{
341
+ * console.log("事件触发",event)
342
+ * })
343
+ * @example
344
+ * // 监听全局document下的子元素a.xx的click事件
345
+ * DOMUtils.on(document,"click tap hover","a.xx",(event)=>{
346
+ * console.log("事件触发",event)
347
+ * })
348
+ */
349
+ on<T extends Event>(
350
+ element: DOMUtilsElementEventType,
351
+ eventType: string,
352
+ selector: string | undefined | null,
353
+ callback: (event: T) => void,
354
+ option?: boolean | AddEventListenerOptions
355
+ ): void;
356
+ on<T extends Event>(
357
+ element:
358
+ | HTMLElement
359
+ | string
360
+ | NodeList
361
+ | HTMLElement[]
362
+ | Window
363
+ | Document
364
+ | Element
365
+ | null
366
+ | typeof globalThis,
367
+ eventType: DOMUtils_EventType | DOMUtils_EventType[] | string,
368
+ selector: string | undefined | ((event: T) => void) | null,
369
+ callback?: ((event: T) => void) | boolean | AddEventListenerOptions,
370
+ option?: boolean | AddEventListenerOptions
371
+ ) {
372
+ /**
373
+ * 获取option配置
374
+ * @param args
375
+ * @param startIndex
376
+ * @param option
377
+ */
378
+ function getOption(
379
+ args: IArguments,
380
+ startIndex: number,
381
+ option: AddEventListenerOptions
382
+ ) {
383
+ if (typeof args[startIndex] === "boolean") {
384
+ option.capture = args[startIndex];
385
+ if (typeof args[startIndex + 1] === "boolean") {
386
+ option.once = args[startIndex + 1];
387
+ }
388
+ if (typeof args[startIndex + 2] === "boolean") {
389
+ option.passive = args[startIndex + 2];
390
+ }
391
+ } else if (
392
+ typeof args[startIndex] === "object" &&
393
+ ("capture" in args[startIndex] ||
394
+ "once" in args[startIndex] ||
395
+ "passive" in args[startIndex])
396
+ ) {
397
+ option.capture = args[startIndex].capture;
398
+ option.once = args[startIndex].once;
399
+ option.passive = args[startIndex].passive;
400
+ }
401
+ return option;
402
+ }
403
+
404
+ let DOMUtilsContext = this;
405
+ let args = arguments;
406
+ if (typeof element === "string") {
407
+ element = DOMUtilsCore.document.querySelectorAll(element);
408
+ }
409
+ if (element == null) {
410
+ return;
411
+ }
412
+ let elementList: HTMLElement[] = [];
413
+ if (element instanceof NodeList || Array.isArray(element)) {
414
+ element = element as HTMLElement[];
415
+ elementList = [...element];
416
+ } else {
417
+ elementList.push(element as HTMLElement);
418
+ }
419
+
420
+ let eventTypeList: string[] = [];
421
+ if (Array.isArray(eventType)) {
422
+ eventTypeList = eventTypeList.concat(eventType as string[]);
423
+ } else if (typeof eventType === "string") {
424
+ eventTypeList = eventTypeList.concat(eventType.split(" "));
425
+ }
426
+ let _selector_: string | undefined = selector as any;
427
+ let _callback_: (event: T) => void = callback as any;
428
+ let _option_: AddEventListenerOptions = {
429
+ capture: false,
430
+ once: false,
431
+ passive: false,
432
+ };
433
+ if (typeof selector === "function") {
434
+ /* 这是为没有selector的情况 */
435
+ _selector_ = void 0;
436
+ _callback_ = selector;
437
+ _option_ = getOption(args, 3, _option_);
438
+ } else {
439
+ /* 这是存在selector的情况 */
440
+ _option_ = getOption(args, 4, _option_);
441
+ }
442
+ /**
443
+ * 如果是once,那么删除该监听和元素上的事件和监听
444
+ */
445
+ function checkOptionOnceToRemoveEventListener() {
446
+ if (_option_.once) {
447
+ DOMUtilsContext.off(
448
+ element,
449
+ eventType as any,
450
+ selector as any,
451
+ callback as any,
452
+ option
453
+ );
454
+ }
455
+ }
456
+ elementList.forEach((elementItem) => {
457
+ function ownCallBack(event: Event) {
458
+ let target = event.target as HTMLElement;
459
+ if (_selector_) {
460
+ /* 存在自定义子元素选择器 */
461
+ let totalParent = DOMUtilsCommonUtils.isWin(elementItem)
462
+ ? DOMUtilsCore.document.documentElement
463
+ : elementItem;
464
+ if (target.matches(_selector_)) {
465
+ /* 当前目标可以被selector所匹配到 */
466
+ _callback_.call(target, event as any);
467
+ checkOptionOnceToRemoveEventListener();
468
+ } else if (
469
+ target.closest(_selector_) &&
470
+ totalParent.contains(target.closest(_selector_))
471
+ ) {
472
+ /* 在上层与主元素之间寻找可以被selector所匹配到的 */
473
+ let closestElement = target.closest(_selector_);
474
+ /* event的target值不能直接修改 */
475
+ OriginPrototype.Object.defineProperty(event, "target", {
476
+ get() {
477
+ return closestElement;
478
+ },
479
+ });
480
+ _callback_.call(closestElement, event as any);
481
+ checkOptionOnceToRemoveEventListener();
482
+ }
483
+ } else {
484
+ _callback_.call(elementItem, event as any);
485
+ checkOptionOnceToRemoveEventListener();
486
+ }
487
+ }
488
+
489
+ /* 遍历事件名设置元素事件 */
490
+ eventTypeList.forEach((eventName) => {
491
+ elementItem.addEventListener(eventName, ownCallBack, _option_);
492
+
493
+ if (_callback_ && (_callback_ as any).delegate) {
494
+ elementItem.setAttribute("data-delegate", _selector_ as string);
495
+ }
496
+ /* 获取对象上的事件 */
497
+ let elementEvents =
498
+ (elementItem as any)[DOMUtilsData.SymbolEvents] || {};
499
+ /* 初始化对象上的xx事件 */
500
+ elementEvents[eventName] = elementEvents[eventName] || [];
501
+ elementEvents[eventName].push({
502
+ selector: _selector_,
503
+ option: _option_,
504
+ callback: ownCallBack,
505
+ originCallBack: _callback_,
506
+ });
507
+ /* 覆盖事件 */
508
+ (elementItem as any)[DOMUtilsData.SymbolEvents] = elementEvents;
509
+ });
510
+ });
511
+ }
512
+ /**
513
+ * 取消绑定事件
514
+ * @param element 需要取消绑定的元素|元素数组
515
+ * @param eventType 需要取消监听的事件
516
+ * @param callback 通过DOMUtils.on绑定的事件函数
517
+ * @param option
518
+ * + capture 如果在添加事件监听器时指定了useCapture为true,则在移除事件监听器时也必须指定为true
519
+ * @param filter (可选)过滤函数,对元素属性上的事件进行过滤出想要删除的事件
520
+ * @example
521
+ * // 取消监听元素a.xx的click事件
522
+ * DOMUtils.off(document.querySelector("a.xx"),"click")
523
+ * DOMUtils.off("a.xx","click")
524
+ */
525
+ off<T extends DOMUtils_EventType>(
526
+ element: DOMUtilsElementEventType,
527
+ eventType: T | T[],
528
+ callback?: (event: DOMUtils_Event[T]) => void,
529
+ option?: boolean | AddEventListenerOptions,
530
+ filter?: (
531
+ value: DOMUtilsEventListenerOptionsAttribute,
532
+ index: number,
533
+ array: DOMUtilsEventListenerOptionsAttribute[]
534
+ ) => boolean
535
+ ): void;
536
+ /**
537
+ * 取消绑定事件
538
+ * @param element 需要取消绑定的元素|元素数组
539
+ * @param eventType 需要取消监听的事件
540
+ * @param callback 通过DOMUtils.on绑定的事件函数
541
+ * @param option
542
+ * + capture 如果在添加事件监听器时指定了useCapture为true,则在移除事件监听器时也必须指定为true
543
+ * @param filter (可选)过滤函数,对元素属性上的事件进行过滤出想要删除的事件
544
+ * @example
545
+ * // 取消监听元素a.xx的click事件
546
+ * DOMUtils.off(document.querySelector("a.xx"),"click")
547
+ * DOMUtils.off("a.xx","click")
548
+ */
549
+ off<T extends Event>(
550
+ element: DOMUtilsElementEventType,
551
+ eventType: string,
552
+ callback?: (event: T) => void,
553
+ option?: boolean | AddEventListenerOptions,
554
+ filter?: (
555
+ value: DOMUtilsEventListenerOptionsAttribute,
556
+ index: number,
557
+ array: DOMUtilsEventListenerOptionsAttribute[]
558
+ ) => boolean
559
+ ): void;
560
+ /**
561
+ * 取消绑定事件
562
+ * @param element 需要取消绑定的元素|元素数组
563
+ * @param eventType 需要取消监听的事件
564
+ * @param selector 子元素选择器
565
+ * @param callback 通过DOMUtils.on绑定的事件函数
566
+ * @param option
567
+ * + capture 如果在添加事件监听器时指定了useCapture为true,则在移除事件监听器时也必须指定为true
568
+ * @param filter (可选)过滤函数,对元素属性上的事件进行过滤出想要删除的事件
569
+ * @example
570
+ * // 取消监听元素a.xx的click、tap、hover事件
571
+ * DOMUtils.off(document.querySelector("a.xx"),"click tap hover")
572
+ * DOMUtils.off("a.xx",["click","tap","hover"])
573
+ */
574
+ off<T extends DOMUtils_EventType>(
575
+ element: DOMUtilsElementEventType,
576
+ eventType: T | T[],
577
+ selector?: string | undefined,
578
+ callback?: (event: DOMUtils_Event[T]) => void,
579
+ option?: boolean | AddEventListenerOptions,
580
+ filter?: (
581
+ value: DOMUtilsEventListenerOptionsAttribute,
582
+ index: number,
583
+ array: DOMUtilsEventListenerOptionsAttribute[]
584
+ ) => boolean
585
+ ): void;
586
+ /**
587
+ * 取消绑定事件
588
+ * @param element 需要取消绑定的元素|元素数组
589
+ * @param eventType 需要取消监听的事件
590
+ * @param selector 子元素选择器
591
+ * @param callback 通过DOMUtils.on绑定的事件函数
592
+ * @param option
593
+ * + capture 如果在添加事件监听器时指定了useCapture为true,则在移除事件监听器时也必须指定为true
594
+ * @param filter (可选)过滤函数,对元素属性上的事件进行过滤出想要删除的事件
595
+ * @example
596
+ * // 取消监听元素a.xx的click、tap、hover事件
597
+ * DOMUtils.off(document.querySelector("a.xx"),"click tap hover")
598
+ * DOMUtils.off("a.xx",["click","tap","hover"])
599
+ */
600
+ off<T extends Event>(
601
+ element: DOMUtilsElementEventType,
602
+ eventType: string,
603
+ selector?: string | undefined,
604
+ callback?: (event: T) => void,
605
+ option?: boolean | AddEventListenerOptions,
606
+ filter?: (
607
+ value: DOMUtilsEventListenerOptionsAttribute,
608
+ index: number,
609
+ array: DOMUtilsEventListenerOptionsAttribute[]
610
+ ) => boolean
611
+ ): void;
612
+ off<T extends Event>(
613
+ element:
614
+ | HTMLElement
615
+ | string
616
+ | NodeList
617
+ | HTMLElement[]
618
+ | Window
619
+ | Document
620
+ | Element
621
+ | null
622
+ | typeof globalThis,
623
+ eventType: DOMUtils_EventType | DOMUtils_EventType[] | string,
624
+ selector?: string | undefined | ((event: T) => void),
625
+ callback?: ((event: T) => void) | boolean | AddEventListenerOptions,
626
+ option?:
627
+ | boolean
628
+ | AddEventListenerOptions
629
+ | ((
630
+ value: DOMUtilsEventListenerOptionsAttribute,
631
+ index: number,
632
+ array: DOMUtilsEventListenerOptionsAttribute[]
633
+ ) => boolean),
634
+ filter?: (
635
+ value: DOMUtilsEventListenerOptionsAttribute,
636
+ index: number,
637
+ array: DOMUtilsEventListenerOptionsAttribute[]
638
+ ) => boolean
639
+ ) {
640
+ /**
641
+ * 获取option配置
642
+ * @param args1
643
+ * @param startIndex
644
+ * @param option
645
+ */
646
+ function getOption(
647
+ args1: IArguments,
648
+ startIndex: number,
649
+ option: EventListenerOptions
650
+ ) {
651
+ if (typeof args1[startIndex] === "boolean") {
652
+ option.capture = args1[startIndex];
653
+ } else if (
654
+ typeof args1[startIndex] === "object" &&
655
+ "capture" in args1[startIndex]
656
+ ) {
657
+ option.capture = args1[startIndex].capture;
658
+ }
659
+ return option;
660
+ }
661
+
662
+ let args = arguments;
663
+ if (typeof element === "string") {
664
+ element = DOMUtilsCore.document.querySelectorAll(element);
665
+ }
666
+ if (element == null) {
667
+ return;
668
+ }
669
+ let elementList: HTMLElement[] = [];
670
+ if (element instanceof NodeList || Array.isArray(element)) {
671
+ element = element as HTMLElement[];
672
+ elementList = [...element];
673
+ } else {
674
+ elementList.push(element as HTMLElement);
675
+ }
676
+ let eventTypeList: string[] = [];
677
+ if (Array.isArray(eventType)) {
678
+ eventTypeList = eventTypeList.concat(eventType as string[]);
679
+ } else if (typeof eventType === "string") {
680
+ eventTypeList = eventTypeList.concat(eventType.split(" "));
681
+ }
682
+ /**
683
+ * 子元素选择器
684
+ */
685
+ let _selector_: string | undefined = selector as any;
686
+ /**
687
+ * 事件的回调函数
688
+ */
689
+ let _callback_: (event: T) => void = callback as any;
690
+
691
+ /**
692
+ * 事件的配置
693
+ */
694
+ let _option_: EventListenerOptions = {
695
+ capture: false,
696
+ };
697
+ if (typeof selector === "function") {
698
+ /* 这是为没有selector的情况 */
699
+ _selector_ = void 0;
700
+ _callback_ = selector;
701
+ _option_ = getOption(args, 3, _option_);
702
+ } else {
703
+ _option_ = getOption(args, 4, _option_);
704
+ }
705
+ elementList.forEach((elementItem) => {
706
+ /* 获取对象上的事件 */
707
+ let elementEvents = (elementItem as any)[DOMUtilsData.SymbolEvents] || {};
708
+ eventTypeList.forEach((eventName) => {
709
+ let handlers: DOMUtilsEventListenerOptionsAttribute[] =
710
+ elementEvents[eventName] || [];
711
+ if (typeof filter === "function") {
712
+ handlers = handlers.filter(filter);
713
+ }
714
+ for (let index = 0; index < handlers.length; index++) {
715
+ let handler = handlers[index];
716
+ let flag = false;
717
+ if (!_selector_ || handler.selector === _selector_) {
718
+ /* selector不为空,进行selector判断 */
719
+ flag = true;
720
+ }
721
+ if (
722
+ !_callback_ ||
723
+ handler.callback === _callback_ ||
724
+ handler.originCallBack === _callback_
725
+ ) {
726
+ /* callback不为空,进行callback判断 */
727
+ flag = true;
728
+ }
729
+
730
+ if (flag) {
731
+ elementItem.removeEventListener(
732
+ eventName,
733
+ handler.callback,
734
+ _option_
735
+ );
736
+ handlers.splice(index--, 1);
737
+ }
738
+ }
739
+ if (handlers.length === 0) {
740
+ /* 如果没有任意的handler,那么删除该属性 */
741
+ DOMUtilsCommonUtils.delete(elementEvents, eventType);
742
+ }
743
+ });
744
+ (elementItem as any)[DOMUtilsData.SymbolEvents] = elementEvents;
745
+ });
746
+ }
747
+ /**
748
+ * 取消绑定所有的事件
749
+ * @param element 需要取消绑定的元素|元素数组
750
+ * @param eventType (可选)需要取消监听的事件
751
+ */
752
+ offAll(element: DOMUtilsElementEventType, eventType?: string): void;
753
+ /**
754
+ * 取消绑定所有的事件
755
+ * @param element 需要取消绑定的元素|元素数组
756
+ * @param eventType (可选)需要取消监听的事件
757
+ */
758
+ offAll(
759
+ element: DOMUtilsElementEventType,
760
+ eventType?: DOMUtils_EventType | DOMUtils_EventType[]
761
+ ): void;
762
+ /**
763
+ * 取消绑定所有的事件
764
+ * @param element 需要取消绑定的元素|元素数组
765
+ * @param eventType (可选)需要取消监听的事件
766
+ */
767
+ offAll(
768
+ element: DOMUtilsElementEventType,
769
+ eventType?: DOMUtils_EventType | DOMUtils_EventType[] | string
770
+ ) {
771
+ if (typeof element === "string") {
772
+ element = DOMUtilsCore.document.querySelectorAll(element);
773
+ }
774
+ if (element == null) {
775
+ return;
776
+ }
777
+ let elementList: HTMLElement[] = [];
778
+ if (element instanceof NodeList || Array.isArray(element)) {
779
+ elementList = [...(element as HTMLElement[])];
780
+ } else {
781
+ elementList.push(element as HTMLElement);
782
+ }
783
+
784
+ let eventTypeList: string[] = [];
785
+ if (Array.isArray(eventType)) {
786
+ eventTypeList = eventTypeList.concat(eventType as string[]);
787
+ } else if (typeof eventType === "string") {
788
+ eventTypeList = eventTypeList.concat(eventType.split(" "));
789
+ }
790
+ elementList.forEach((elementItem) => {
791
+ Object.getOwnPropertySymbols(elementItem).forEach((symbolEvents) => {
792
+ if (!symbolEvents.toString().startsWith("Symbol(events_")) {
793
+ return;
794
+ }
795
+ let elementEvents = (elementItem as any)[symbolEvents] || {};
796
+ let iterEventNameList = eventTypeList.length
797
+ ? eventTypeList
798
+ : Object.keys(elementEvents);
799
+ iterEventNameList.forEach((eventName) => {
800
+ let handlers = elementEvents[eventName];
801
+ if (!handlers) {
802
+ return;
803
+ }
804
+ for (const handler of handlers) {
805
+ elementItem.removeEventListener(eventName, handler.callback, {
806
+ capture: handler["option"]["capture"],
807
+ });
808
+ }
809
+ DOMUtilsCommonUtils.delete(
810
+ (elementItem as any)[symbolEvents],
811
+ eventName
812
+ );
813
+ });
814
+ });
815
+ });
816
+ }
817
+
818
+ /**
819
+ * 等待文档加载完成后执行指定的函数
820
+ * @param callback 需要执行的函数
821
+ * @example
822
+ * DOMUtils.ready(function(){
823
+ * console.log("文档加载完毕")
824
+ * })
825
+ */
826
+ ready<T extends Function>(callback: T) {
827
+ if (typeof callback !== "function") {
828
+ return;
829
+ }
830
+ /**
831
+ * 检测文档是否加载完毕
832
+ */
833
+ function checkDOMReadyState() {
834
+ try {
835
+ if (
836
+ DOMUtilsCore.document.readyState === "complete" ||
837
+ (DOMUtilsCore.document.readyState !== "loading" &&
838
+ !(DOMUtilsCore.document.documentElement as any).doScroll)
839
+ ) {
840
+ return true;
841
+ } else {
842
+ return false;
843
+ }
844
+ } catch (error) {
845
+ return false;
846
+ }
847
+ }
848
+ /**
849
+ * 成功加载完毕后触发的回调函数
850
+ */
851
+ function completed() {
852
+ removeDomReadyListener();
853
+ callback();
854
+ }
855
+
856
+ let targetList = [
857
+ {
858
+ target: DOMUtilsCore.document,
859
+ eventType: "DOMContentLoaded",
860
+ callback: completed,
861
+ },
862
+ {
863
+ target: DOMUtilsCore.window,
864
+ eventType: "load",
865
+ callback: completed,
866
+ },
867
+ ];
868
+ /**
869
+ * 添加监听
870
+ */
871
+ function addDomReadyListener() {
872
+ for (let index = 0; index < targetList.length; index++) {
873
+ let item = targetList[index];
874
+ item.target.addEventListener(item.eventType, item.callback);
875
+ }
876
+ }
877
+ /**
878
+ * 移除监听
879
+ */
880
+ function removeDomReadyListener() {
881
+ for (let index = 0; index < targetList.length; index++) {
882
+ let item = targetList[index];
883
+ item.target.removeEventListener(item.eventType, item.callback);
884
+ }
885
+ }
886
+ if (checkDOMReadyState()) {
887
+ /* 检查document状态 */
888
+ setTimeout(callback);
889
+ } else {
890
+ /* 添加监听 */
891
+ addDomReadyListener();
892
+ }
893
+ }
894
+ /**
895
+ * 主动触发事件
896
+ * @param element 需要触发的元素|元素数组|window
897
+ * @param eventType 需要触发的事件
898
+ * @param details 赋予触发的Event的额外属性,如果是Event类型,那么将自动代替默认new的Event对象
899
+ * @param useDispatchToTriggerEvent 是否使用dispatchEvent来触发事件,默认true
900
+ * @example
901
+ * // 触发元素a.xx的click事件
902
+ * DOMUtils.trigger(document.querySelector("a.xx"),"click")
903
+ * DOMUtils.trigger("a.xx","click")
904
+ * // 触发元素a.xx的click、tap、hover事件
905
+ * DOMUtils.trigger(document.querySelector("a.xx"),"click tap hover")
906
+ * DOMUtils.trigger("a.xx",["click","tap","hover"])
907
+ */
908
+ trigger(
909
+ element: HTMLElement | string | NodeList | any[] | Window | Document,
910
+ eventType: string,
911
+ details?: object,
912
+ useDispatchToTriggerEvent?: boolean
913
+ ): void;
914
+ /**
915
+ * 主动触发事件
916
+ * @param element 需要触发的元素|元素数组|window
917
+ * @param eventType 需要触发的事件
918
+ * @param details 赋予触发的Event的额外属性,如果是Event类型,那么将自动代替默认new的Event对象
919
+ * @param useDispatchToTriggerEvent 是否使用dispatchEvent来触发事件,默认true
920
+ * @example
921
+ * // 触发元素a.xx的click事件
922
+ * DOMUtils.trigger(document.querySelector("a.xx"),"click")
923
+ * DOMUtils.trigger("a.xx","click")
924
+ * // 触发元素a.xx的click、tap、hover事件
925
+ * DOMUtils.trigger(document.querySelector("a.xx"),"click tap hover")
926
+ * DOMUtils.trigger("a.xx",["click","tap","hover"])
927
+ */
928
+ trigger(
929
+ element: HTMLElement | string | NodeList | any[] | Window | Document,
930
+ eventType: DOMUtils_EventType | DOMUtils_EventType[],
931
+ details?: object,
932
+ useDispatchToTriggerEvent?: boolean
933
+ ): void;
934
+ /**
935
+ * 主动触发事件
936
+ * @param element 需要触发的元素|元素数组|window
937
+ * @param eventType 需要触发的事件
938
+ * @param details 赋予触发的Event的额外属性,如果是Event类型,那么将自动代替默认new的Event对象
939
+ * @param useDispatchToTriggerEvent 是否使用dispatchEvent来触发事件,默认true
940
+ * @example
941
+ * // 触发元素a.xx的click事件
942
+ * DOMUtils.trigger(document.querySelector("a.xx"),"click")
943
+ * DOMUtils.trigger("a.xx","click")
944
+ * // 触发元素a.xx的click、tap、hover事件
945
+ * DOMUtils.trigger(document.querySelector("a.xx"),"click tap hover")
946
+ * DOMUtils.trigger("a.xx",["click","tap","hover"])
947
+ */
948
+ trigger(
949
+ element: HTMLElement | string | NodeList | any[] | Window | Document,
950
+ eventType: DOMUtils_EventType | DOMUtils_EventType[] | string,
951
+ details?: object,
952
+ useDispatchToTriggerEvent: boolean = true
953
+ ) {
954
+ if (typeof element === "string") {
955
+ element = DOMUtilsCore.document.querySelector(element) as HTMLElement;
956
+ }
957
+ if (element == null) {
958
+ return;
959
+ }
960
+ let elementList = [];
961
+ if (element instanceof NodeList || Array.isArray(element)) {
962
+ element = element as HTMLElement[];
963
+ elementList = [...element];
964
+ } else {
965
+ elementList = [element];
966
+ }
967
+ let eventTypeList: string[] = [];
968
+ if (Array.isArray(eventType)) {
969
+ eventTypeList = eventType as string[];
970
+ } else if (typeof eventType === "string") {
971
+ eventTypeList = eventType.split(" ");
972
+ }
973
+
974
+ elementList.forEach((elementItem) => {
975
+ /* 获取对象上的事件 */
976
+ let events = elementItem[DOMUtilsData.SymbolEvents] || {};
977
+ eventTypeList.forEach((_eventType_) => {
978
+ let event: Event = null as any;
979
+ if (details && details instanceof Event) {
980
+ event = details;
981
+ } else {
982
+ event = new Event(_eventType_);
983
+ if (details) {
984
+ Object.keys(details).forEach((keyName) => {
985
+ (event as any)[keyName] = (details as any)[keyName];
986
+ });
987
+ }
988
+ }
989
+ if (useDispatchToTriggerEvent == false && _eventType_ in events) {
990
+ events[_eventType_].forEach((eventsItem: any) => {
991
+ eventsItem.callback(event);
992
+ });
993
+ } else {
994
+ elementItem.dispatchEvent(event);
995
+ }
996
+ });
997
+ });
998
+ }
999
+
1000
+ /**
1001
+ * 绑定或触发元素的click事件
1002
+ * @param element 目标元素
1003
+ * @param handler (可选)事件处理函数
1004
+ * @param details (可选)赋予触发的Event的额外属性
1005
+ * @param useDispatchToTriggerEvent (可选)是否使用dispatchEvent来触发事件,默认true
1006
+ * @example
1007
+ * // 触发元素a.xx的click事件
1008
+ * DOMUtils.click(document.querySelector("a.xx"))
1009
+ * DOMUtils.click("a.xx")
1010
+ * DOMUtils.click("a.xx",function(){
1011
+ * console.log("触发click事件成功")
1012
+ * })
1013
+ * */
1014
+ click(
1015
+ element: HTMLElement | string | Window,
1016
+ handler?: (event: DOMUtils_Event["click"]) => void,
1017
+ details?: any,
1018
+ useDispatchToTriggerEvent?: boolean
1019
+ ) {
1020
+ let DOMUtilsContext = this;
1021
+ if (typeof element === "string") {
1022
+ element = DOMUtilsCore.document.querySelector(element) as HTMLElement;
1023
+ }
1024
+ if (element == null) {
1025
+ return;
1026
+ }
1027
+ if (handler == null) {
1028
+ DOMUtilsContext.trigger(
1029
+ element,
1030
+ "click",
1031
+ details,
1032
+ useDispatchToTriggerEvent
1033
+ );
1034
+ } else {
1035
+ DOMUtilsContext.on(element, "click", null, handler);
1036
+ }
1037
+ }
1038
+ /**
1039
+ * 绑定或触发元素的blur事件
1040
+ * @param element 目标元素
1041
+ * @param handler (可选)事件处理函数
1042
+ * @param details (可选)赋予触发的Event的额外属性
1043
+ * @param useDispatchToTriggerEvent (可选)是否使用dispatchEvent来触发事件,默认true
1044
+ * @example
1045
+ * // 触发元素a.xx的blur事件
1046
+ * DOMUtils.blur(document.querySelector("a.xx"))
1047
+ * DOMUtils.blur("a.xx")
1048
+ * DOMUtils.blur("a.xx",function(){
1049
+ * console.log("触发blur事件成功")
1050
+ * })
1051
+ * */
1052
+ blur(
1053
+ element: HTMLElement | string | Window,
1054
+ handler?: (event: DOMUtils_Event["blur"]) => void,
1055
+ details?: object,
1056
+ useDispatchToTriggerEvent?: boolean
1057
+ ) {
1058
+ let DOMUtilsContext = this;
1059
+ if (typeof element === "string") {
1060
+ element = DOMUtilsCore.document.querySelector(element) as HTMLElement;
1061
+ }
1062
+ if (element == null) {
1063
+ return;
1064
+ }
1065
+ if (handler === null) {
1066
+ DOMUtilsContext.trigger(
1067
+ element,
1068
+ "blur",
1069
+ details,
1070
+ useDispatchToTriggerEvent
1071
+ );
1072
+ } else {
1073
+ DOMUtilsContext.on(
1074
+ element,
1075
+ "blur",
1076
+ null,
1077
+ handler as (event: Event) => void
1078
+ );
1079
+ }
1080
+ }
1081
+ /**
1082
+ * 绑定或触发元素的focus事件
1083
+ * @param element 目标元素
1084
+ * @param handler (可选)事件处理函数
1085
+ * @param details (可选)赋予触发的Event的额外属性
1086
+ * @param useDispatchToTriggerEvent (可选)是否使用dispatchEvent来触发事件,默认true
1087
+ * @example
1088
+ * // 触发元素a.xx的focus事件
1089
+ * DOMUtils.focus(document.querySelector("a.xx"))
1090
+ * DOMUtils.focus("a.xx")
1091
+ * DOMUtils.focus("a.xx",function(){
1092
+ * console.log("触发focus事件成功")
1093
+ * })
1094
+ * */
1095
+ focus(
1096
+ element: HTMLElement | string | Window,
1097
+ handler?: (event: DOMUtils_Event["focus"]) => void,
1098
+ details?: object,
1099
+ useDispatchToTriggerEvent?: boolean
1100
+ ) {
1101
+ let DOMUtilsContext = this;
1102
+ if (typeof element === "string") {
1103
+ element = DOMUtilsCore.document.querySelector(element) as HTMLElement;
1104
+ }
1105
+ if (element == null) {
1106
+ return;
1107
+ }
1108
+ if (handler == null) {
1109
+ DOMUtilsContext.trigger(
1110
+ element,
1111
+ "focus",
1112
+ details,
1113
+ useDispatchToTriggerEvent
1114
+ );
1115
+ } else {
1116
+ DOMUtilsContext.on(element, "focus", null, handler);
1117
+ }
1118
+ }
1119
+ /**
1120
+ * 当鼠标移入或移出元素时触发事件
1121
+ * @param element 当前元素
1122
+ * @param handler 事件处理函数
1123
+ * @param option 配置
1124
+ * @example
1125
+ * // 监听a.xx元素的移入或移出
1126
+ * DOMUtils.hover(document.querySelector("a.xx"),()=>{
1127
+ * console.log("移入/移除");
1128
+ * })
1129
+ * DOMUtils.hover("a.xx",()=>{
1130
+ * console.log("移入/移除");
1131
+ * })
1132
+ */
1133
+ hover(
1134
+ element: HTMLElement | string,
1135
+ handler: (event: DOMUtils_Event["hover"]) => void,
1136
+ option?: boolean | AddEventListenerOptions
1137
+ ) {
1138
+ let DOMUtilsContext = this;
1139
+ if (typeof element === "string") {
1140
+ element = DOMUtilsCore.document.querySelector(element) as HTMLElement;
1141
+ }
1142
+ if (element == null) {
1143
+ return;
1144
+ }
1145
+ DOMUtilsContext.on(element, "mouseenter", null, handler, option);
1146
+ DOMUtilsContext.on(element, "mouseleave", null, handler, option);
1147
+ }
1148
+ /**
1149
+ * 当按键松开时触发事件
1150
+ * keydown - > keypress - > keyup
1151
+ * @param target 当前元素
1152
+ * @param handler 事件处理函数
1153
+ * @param option 配置
1154
+ * @example
1155
+ * // 监听a.xx元素的按键松开
1156
+ * DOMUtils.keyup(document.querySelector("a.xx"),()=>{
1157
+ * console.log("按键松开");
1158
+ * })
1159
+ * DOMUtils.keyup("a.xx",()=>{
1160
+ * console.log("按键松开");
1161
+ * })
1162
+ */
1163
+ keyup(
1164
+ target: HTMLElement | string | Window | typeof globalThis,
1165
+ handler: (event: DOMUtils_Event["keyup"]) => void,
1166
+ option?: boolean | AddEventListenerOptions
1167
+ ) {
1168
+ let DOMUtilsContext = this;
1169
+ if (target == null) {
1170
+ return;
1171
+ }
1172
+ if (typeof target === "string") {
1173
+ target = DOMUtilsCore.document.querySelector(target) as HTMLElement;
1174
+ }
1175
+ DOMUtilsContext.on(target, "keyup", null, handler, option);
1176
+ }
1177
+ /**
1178
+ * 当按键按下时触发事件
1179
+ * keydown - > keypress - > keyup
1180
+ * @param target 目标
1181
+ * @param handler 事件处理函数
1182
+ * @param option 配置
1183
+ * @example
1184
+ * // 监听a.xx元素的按键按下
1185
+ * DOMUtils.keydown(document.querySelector("a.xx"),()=>{
1186
+ * console.log("按键按下");
1187
+ * })
1188
+ * DOMUtils.keydown("a.xx",()=>{
1189
+ * console.log("按键按下");
1190
+ * })
1191
+ */
1192
+ keydown(
1193
+ target: HTMLElement | Window | typeof globalThis | string,
1194
+ handler: (event: DOMUtils_Event["keydown"]) => void,
1195
+ option?: boolean | AddEventListenerOptions
1196
+ ) {
1197
+ let DOMUtilsContext = this;
1198
+ if (target == null) {
1199
+ return;
1200
+ }
1201
+ if (typeof target === "string") {
1202
+ target = DOMUtilsCore.document.querySelector(target) as HTMLElement;
1203
+ }
1204
+ DOMUtilsContext.on(target, "keydown", null, handler, option);
1205
+ }
1206
+ /**
1207
+ * 当按键按下时触发事件
1208
+ * keydown - > keypress - > keyup
1209
+ * @param target 目标
1210
+ * @param handler 事件处理函数
1211
+ * @param option 配置
1212
+ * @example
1213
+ * // 监听a.xx元素的按键按下
1214
+ * DOMUtils.keypress(document.querySelector("a.xx"),()=>{
1215
+ * console.log("按键按下");
1216
+ * })
1217
+ * DOMUtils.keypress("a.xx",()=>{
1218
+ * console.log("按键按下");
1219
+ * })
1220
+ */
1221
+ keypress(
1222
+ target: HTMLElement | Window | typeof globalThis | string,
1223
+ handler: (event: DOMUtils_Event["keypress"]) => void,
1224
+ option?: boolean | AddEventListenerOptions
1225
+ ) {
1226
+ let DOMUtilsContext = this;
1227
+ if (target == null) {
1228
+ return;
1229
+ }
1230
+ if (typeof target === "string") {
1231
+ target = DOMUtilsCore.document.querySelector(target) as HTMLElement;
1232
+ }
1233
+ DOMUtilsContext.on(target, "keypress", null, handler, option);
1234
+ }
1235
+ }
1236
+
1237
+ export { DOMUtilsEvent };