@whitesev/domutils 1.6.8 → 1.7.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.
Files changed (55) hide show
  1. package/dist/index.amd.js +1928 -1047
  2. package/dist/index.amd.js.map +1 -1
  3. package/dist/index.amd.min.js +2 -0
  4. package/dist/index.amd.min.js.map +1 -0
  5. package/dist/index.cjs.js +1928 -1047
  6. package/dist/index.cjs.js.map +1 -1
  7. package/dist/index.cjs.min.js +2 -0
  8. package/dist/index.cjs.min.js.map +1 -0
  9. package/dist/index.esm.js +1928 -1047
  10. package/dist/index.esm.js.map +1 -1
  11. package/dist/index.esm.min.js +2 -0
  12. package/dist/index.esm.min.js.map +1 -0
  13. package/dist/index.iife.js +1928 -1047
  14. package/dist/index.iife.js.map +1 -1
  15. package/dist/index.iife.min.js +2 -0
  16. package/dist/index.iife.min.js.map +1 -0
  17. package/dist/index.system.js +1928 -1047
  18. package/dist/index.system.js.map +1 -1
  19. package/dist/index.system.min.js +2 -0
  20. package/dist/index.system.min.js.map +1 -0
  21. package/dist/index.umd.js +1928 -1047
  22. package/dist/index.umd.js.map +1 -1
  23. package/dist/index.umd.min.js +2 -0
  24. package/dist/index.umd.min.js.map +1 -0
  25. package/dist/types/index.d.ts +1 -1
  26. package/dist/types/src/{DOMUtilsCommonUtils.d.ts → CommonUtils.d.ts} +20 -8
  27. package/dist/types/src/ElementAnimate.d.ts +89 -0
  28. package/dist/types/src/{DOMUtilsEvent.d.ts → ElementEvent.d.ts} +19 -84
  29. package/dist/types/src/ElementHandler.d.ts +17 -0
  30. package/dist/types/src/ElementSelector.d.ts +96 -0
  31. package/dist/types/src/ElementWait.d.ts +278 -0
  32. package/dist/types/src/GlobalData.d.ts +4 -0
  33. package/dist/types/src/{DOMUtilsOriginPrototype.d.ts → OriginPrototype.d.ts} +1 -2
  34. package/dist/types/src/Utils.d.ts +68 -0
  35. package/dist/types/src/{DOMUtils.d.ts → index.d.ts} +157 -177
  36. package/dist/types/src/types/env.d.ts +9 -0
  37. package/dist/types/src/types/global.d.ts +0 -2
  38. package/dist/types/src/types/gm.d.ts +0 -4
  39. package/index.ts +1 -1
  40. package/package.json +6 -2
  41. package/src/{DOMUtilsCommonUtils.ts → CommonUtils.ts} +25 -11
  42. package/src/ElementAnimate.ts +290 -0
  43. package/src/{DOMUtilsEvent.ts → ElementEvent.ts} +166 -361
  44. package/src/ElementHandler.ts +43 -0
  45. package/src/ElementSelector.ts +260 -0
  46. package/src/ElementWait.ts +699 -0
  47. package/src/GlobalData.ts +5 -0
  48. package/src/{DOMUtilsOriginPrototype.ts → OriginPrototype.ts} +1 -3
  49. package/src/Utils.ts +386 -0
  50. package/src/{DOMUtils.ts → index.ts} +678 -757
  51. package/src/types/env.d.ts +9 -0
  52. package/src/types/global.d.ts +0 -2
  53. package/src/types/gm.d.ts +0 -4
  54. package/dist/types/src/DOMUtilsData.d.ts +0 -5
  55. package/src/DOMUtilsData.ts +0 -7
@@ -1,6 +1,7 @@
1
- import { DOMUtilsCommonUtils } from "./DOMUtilsCommonUtils";
2
- import { DOMUtilsData } from "./DOMUtilsData";
3
- import { OriginPrototype } from "./DOMUtilsOriginPrototype";
1
+ import { CommonUtils } from "./CommonUtils";
2
+ import { GlobalData } from "./GlobalData";
3
+ import { ElementAnimate } from "./ElementAnimate";
4
+ import { OriginPrototype } from "./OriginPrototype";
4
5
  import type {
5
6
  DOMUtils_Event,
6
7
  DOMUtils_EventType,
@@ -12,11 +13,20 @@ import type { DOMUtilsTargetElementType } from "./types/global";
12
13
  import type { WindowApiOption } from "./types/WindowApi";
13
14
  import { WindowApi } from "./WindowApi";
14
15
 
15
- export class DOMUtilsEvent {
16
+ class ElementEvent extends ElementAnimate {
16
17
  windowApi: typeof WindowApi.prototype;
17
18
  constructor(windowApiOption?: WindowApiOption) {
19
+ super(windowApiOption);
18
20
  this.windowApi = new WindowApi(windowApiOption);
19
21
  }
22
+ /** 获取 animationend 在各个浏览器的兼容名 */
23
+ getAnimationEndNameList() {
24
+ return CommonUtils.getAnimationEndNameList();
25
+ }
26
+ /** 获取 transitionend 在各个浏览器的兼容名 */
27
+ getTransitionEndNameList() {
28
+ return CommonUtils.getTransitionEndNameList();
29
+ }
20
30
  /**
21
31
  * 绑定事件
22
32
  * @param element 需要绑定的元素|元素数组|window
@@ -173,11 +183,11 @@ export class DOMUtilsEvent {
173
183
  return option;
174
184
  }
175
185
 
176
- const DOMUtilsContext = this;
186
+ const that = this;
177
187
  // eslint-disable-next-line prefer-rest-params
178
188
  const args = arguments;
179
189
  if (typeof element === "string") {
180
- element = DOMUtilsContext.selectorAll(element);
190
+ element = that.selectorAll(element);
181
191
  }
182
192
  if (element == null) {
183
193
  return;
@@ -230,7 +240,7 @@ export class DOMUtilsEvent {
230
240
  */
231
241
  function checkOptionOnceToRemoveEventListener() {
232
242
  if (listenerOption.once) {
233
- DOMUtilsContext.off(element, eventType as any, selector as any, callback as any, option);
243
+ that.off(element, eventType as any, selector as any, callback as any, option);
234
244
  }
235
245
  }
236
246
  elementList.forEach((elementItem) => {
@@ -246,19 +256,19 @@ export class DOMUtilsEvent {
246
256
  ? (event.composedPath()[0] as HTMLElement)
247
257
  : (event.target as HTMLElement);
248
258
  let totalParent = elementItem;
249
- if (DOMUtilsCommonUtils.isWin(totalParent)) {
250
- if (totalParent === (DOMUtilsContext.windowApi.document as any as HTMLElement)) {
251
- totalParent = DOMUtilsContext.windowApi.document.documentElement;
259
+ if (CommonUtils.isWin(totalParent)) {
260
+ if (totalParent === (that.windowApi.document as any as HTMLElement)) {
261
+ totalParent = that.windowApi.document.documentElement;
252
262
  }
253
263
  }
254
264
  const findValue = selectorList.find((selectorItem) => {
255
265
  // 判断目标元素是否匹配选择器
256
- if (DOMUtilsContext.matches(eventTarget, selectorItem)) {
266
+ if (that.matches(eventTarget, selectorItem)) {
257
267
  /* 当前目标可以被selector所匹配到 */
258
268
  return true;
259
269
  }
260
270
  /* 在上层与主元素之间寻找可以被selector所匹配到的 */
261
- const $closestMatches = DOMUtilsContext.closest<HTMLElement>(eventTarget, selectorItem);
271
+ const $closestMatches = that.closest<HTMLElement>(eventTarget, selectorItem);
262
272
  if ($closestMatches && totalParent?.contains($closestMatches)) {
263
273
  eventTarget = $closestMatches;
264
274
  return true;
@@ -292,7 +302,7 @@ export class DOMUtilsEvent {
292
302
  /* 获取对象上的事件 */
293
303
  const elementEvents: {
294
304
  [k: string]: DOMUtilsEventListenerOptionsAttribute[];
295
- } = Reflect.get(elementItem, DOMUtilsData.SymbolEvents) || {};
305
+ } = Reflect.get(elementItem, GlobalData.domEventSymbol) || {};
296
306
  /* 初始化对象上的xx事件 */
297
307
  elementEvents[eventName] = elementEvents[eventName] || [];
298
308
  elementEvents[eventName].push({
@@ -302,7 +312,7 @@ export class DOMUtilsEvent {
302
312
  originCallBack: listenerCallBack,
303
313
  });
304
314
  /* 覆盖事件 */
305
- Reflect.set(elementItem, DOMUtilsData.SymbolEvents, elementEvents);
315
+ Reflect.set(elementItem, GlobalData.domEventSymbol, elementEvents);
306
316
  });
307
317
  });
308
318
  }
@@ -445,21 +455,21 @@ export class DOMUtilsEvent {
445
455
  }
446
456
  return option;
447
457
  }
448
- const DOMUtilsContext = this;
458
+ const that = this;
449
459
  // eslint-disable-next-line prefer-rest-params
450
460
  const args = arguments;
451
461
  if (typeof element === "string") {
452
- element = DOMUtilsContext.selectorAll(element);
462
+ element = that.selectorAll(element);
453
463
  }
454
464
  if (element == null) {
455
465
  return;
456
466
  }
457
- let elementList: HTMLElement[] = [];
467
+ let $elList: HTMLElement[] = [];
458
468
  if (element instanceof NodeList || Array.isArray(element)) {
459
469
  element = element as HTMLElement[];
460
- elementList = [...element];
470
+ $elList = [...element];
461
471
  } else {
462
- elementList.push(element as HTMLElement);
472
+ $elList.push(element as HTMLElement);
463
473
  }
464
474
  let eventTypeList: string[] = [];
465
475
  if (Array.isArray(eventType)) {
@@ -515,11 +525,11 @@ export class DOMUtilsEvent {
515
525
  array: DOMUtilsEventListenerOptionsAttribute[]
516
526
  ) => boolean;
517
527
  }
518
- elementList.forEach((elementItem) => {
528
+ $elList.forEach(($elItem) => {
519
529
  /* 获取对象上的事件 */
520
530
  const elementEvents: {
521
531
  [key: string]: DOMUtilsEventListenerOptionsAttribute[];
522
- } = Reflect.get(elementItem, DOMUtilsData.SymbolEvents) || {};
532
+ } = Reflect.get($elItem, GlobalData.domEventSymbol) || {};
523
533
  eventTypeList.forEach((eventName) => {
524
534
  const handlers = elementEvents[eventName] || [];
525
535
  const filterHandler = typeof filter === "function" ? handlers.filter(filter) : handlers;
@@ -545,7 +555,7 @@ export class DOMUtilsEvent {
545
555
  flag = false;
546
556
  }
547
557
  if (flag || isRemoveAll) {
548
- elementItem.removeEventListener(eventName, handler.callback, handler.option);
558
+ $elItem.removeEventListener(eventName, handler.callback, handler.option);
549
559
  const findIndex = handlers.findIndex((item) => item === handler);
550
560
  if (findIndex !== -1) {
551
561
  handlers.splice(findIndex, 1);
@@ -554,10 +564,10 @@ export class DOMUtilsEvent {
554
564
  }
555
565
  if (handlers.length === 0) {
556
566
  /* 如果没有任意的handler,那么删除该属性 */
557
- DOMUtilsCommonUtils.delete(elementEvents, eventType);
567
+ CommonUtils.delete(elementEvents, eventType);
558
568
  }
559
569
  });
560
- Reflect.set(elementItem, DOMUtilsData.SymbolEvents, elementEvents);
570
+ Reflect.set($elItem, GlobalData.domEventSymbol, elementEvents);
561
571
  });
562
572
  }
563
573
  /**
@@ -578,18 +588,18 @@ export class DOMUtilsEvent {
578
588
  * @param eventType (可选)需要取消监听的事件
579
589
  */
580
590
  offAll(element: DOMUtilsElementEventType, eventType?: DOMUtils_EventType | DOMUtils_EventType[] | string) {
581
- const DOMUtilsContext = this;
591
+ const that = this;
582
592
  if (typeof element === "string") {
583
- element = DOMUtilsContext.selectorAll(element);
593
+ element = that.selectorAll(element);
584
594
  }
585
595
  if (element == null) {
586
596
  return;
587
597
  }
588
- let elementList: HTMLElement[] = [];
598
+ let $elList: HTMLElement[] = [];
589
599
  if (element instanceof NodeList || Array.isArray(element)) {
590
- elementList = [...(element as HTMLElement[])];
600
+ $elList = [...(element as HTMLElement[])];
591
601
  } else {
592
- elementList.push(element as HTMLElement);
602
+ $elList.push(element as HTMLElement);
593
603
  }
594
604
 
595
605
  let eventTypeList: string[] = [];
@@ -598,12 +608,15 @@ export class DOMUtilsEvent {
598
608
  } else if (typeof eventType === "string") {
599
609
  eventTypeList = eventTypeList.concat(eventType.split(" "));
600
610
  }
601
- elementList.forEach((elementItem) => {
602
- Object.getOwnPropertySymbols(elementItem).forEach((symbolEvents) => {
603
- if (!symbolEvents.toString().startsWith("Symbol(events_")) {
611
+ $elList.forEach(($elItem) => {
612
+ const symbolList = [...new Set([...Object.getOwnPropertySymbols($elItem), GlobalData.domEventSymbol])];
613
+ symbolList.forEach((symbolItem) => {
614
+ if (!symbolItem.toString().startsWith("Symbol(events_")) {
604
615
  return;
605
616
  }
606
- const elementEvents = (elementItem as any)[symbolEvents] || {};
617
+ const elementEvents: {
618
+ [key: string]: DOMUtilsEventListenerOptionsAttribute[];
619
+ } = Reflect.get($elItem, symbolItem) || {};
607
620
  const iterEventNameList = eventTypeList.length ? eventTypeList : Object.keys(elementEvents);
608
621
  iterEventNameList.forEach((eventName) => {
609
622
  const handlers: DOMUtilsEventListenerOptionsAttribute[] = elementEvents[eventName];
@@ -611,12 +624,12 @@ export class DOMUtilsEvent {
611
624
  return;
612
625
  }
613
626
  for (const handler of handlers) {
614
- elementItem.removeEventListener(eventName, handler.callback, {
627
+ $elItem.removeEventListener(eventName, handler.callback, {
615
628
  capture: handler["option"]["capture"],
616
629
  });
617
630
  }
618
- const events = Reflect.get(elementItem, symbolEvents);
619
- DOMUtilsCommonUtils.delete(events, eventName);
631
+ const events = Reflect.get($elItem, symbolItem);
632
+ CommonUtils.delete(events, eventName);
620
633
  });
621
634
  });
622
635
  });
@@ -634,16 +647,16 @@ export class DOMUtilsEvent {
634
647
  if (typeof callback !== "function") {
635
648
  return;
636
649
  }
637
- const DOMUtilsContext = this;
650
+ const that = this;
638
651
  /**
639
652
  * 检测文档是否加载完毕
640
653
  */
641
654
  function checkDOMReadyState() {
642
655
  try {
643
656
  if (
644
- DOMUtilsContext.windowApi.document.readyState === "complete" ||
645
- (DOMUtilsContext.windowApi.document.readyState !== "loading" &&
646
- !(DOMUtilsContext.windowApi.document.documentElement as any).doScroll)
657
+ that.windowApi.document.readyState === "complete" ||
658
+ (that.windowApi.document.readyState !== "loading" &&
659
+ !(that.windowApi.document.documentElement as any).doScroll)
647
660
  ) {
648
661
  return true;
649
662
  } else {
@@ -663,12 +676,12 @@ export class DOMUtilsEvent {
663
676
 
664
677
  const targetList = [
665
678
  {
666
- target: DOMUtilsContext.windowApi.document,
679
+ target: that.windowApi.document,
667
680
  eventType: "DOMContentLoaded",
668
681
  callback: completed,
669
682
  },
670
683
  {
671
- target: DOMUtilsContext.windowApi.window,
684
+ target: that.windowApi.window,
672
685
  eventType: "load",
673
686
  callback: completed,
674
687
  },
@@ -693,7 +706,7 @@ export class DOMUtilsEvent {
693
706
  }
694
707
  if (checkDOMReadyState()) {
695
708
  /* 检查document状态 */
696
- DOMUtilsCommonUtils.setTimeout(callback);
709
+ CommonUtils.setTimeout(callback);
697
710
  } else {
698
711
  /* 添加监听 */
699
712
  addDomReadyListener();
@@ -724,7 +737,7 @@ export class DOMUtilsEvent {
724
737
  * @param element 需要触发的元素|元素数组|window
725
738
  * @param eventType 需要触发的事件
726
739
  * @param details 赋予触发的Event的额外属性,如果是Event类型,那么将自动代替默认new的Event对象
727
- * @param useDispatchToTriggerEvent 是否使用dispatchEvent来触发事件,默认true
740
+ * @param useDispatchToTriggerEvent 是否使用dispatchEvent来触发事件,默认true,false的话就直接触发获取使用DOMUtils进行监听的事件
728
741
  * @example
729
742
  * // 触发元素a.xx的click事件
730
743
  * DOMUtils.trigger(document.querySelector("a.xx"),"click")
@@ -744,7 +757,7 @@ export class DOMUtilsEvent {
744
757
  * @param element 需要触发的元素|元素数组|window
745
758
  * @param eventType 需要触发的事件
746
759
  * @param details 赋予触发的Event的额外属性,如果是Event类型,那么将自动代替默认new的Event对象
747
- * @param useDispatchToTriggerEvent 是否使用dispatchEvent来触发事件,默认true
760
+ * @param useDispatchToTriggerEvent 是否使用dispatchEvent来触发事件,默认true
748
761
  * @example
749
762
  * // 触发元素a.xx的click事件
750
763
  * DOMUtils.trigger(document.querySelector("a.xx"),"click")
@@ -759,19 +772,19 @@ export class DOMUtilsEvent {
759
772
  details?: object,
760
773
  useDispatchToTriggerEvent: boolean = true
761
774
  ) {
762
- const DOMUtilsContext = this;
775
+ const that = this;
763
776
  if (typeof element === "string") {
764
- element = DOMUtilsContext.selectorAll(element);
777
+ element = that.selectorAll(element);
765
778
  }
766
779
  if (element == null) {
767
780
  return;
768
781
  }
769
- let elementList = [];
782
+ let $elList = [];
770
783
  if (element instanceof NodeList || Array.isArray(element)) {
771
784
  element = element as HTMLElement[];
772
- elementList = [...element];
785
+ $elList = [...element];
773
786
  } else {
774
- elementList = [element];
787
+ $elList = [element];
775
788
  }
776
789
  let eventTypeList: string[] = [];
777
790
  if (Array.isArray(eventType)) {
@@ -780,27 +793,33 @@ export class DOMUtilsEvent {
780
793
  eventTypeList = eventType.split(" ");
781
794
  }
782
795
 
783
- elementList.forEach((elementItem) => {
796
+ $elList.forEach(($elItem) => {
784
797
  /* 获取对象上的事件 */
785
- const events = elementItem[DOMUtilsData.SymbolEvents] || {};
786
- eventTypeList.forEach((_eventType_) => {
798
+ const elementEvents: {
799
+ [key: string]: DOMUtilsEventListenerOptionsAttribute[];
800
+ } = Reflect.get($elItem, GlobalData.domEventSymbol) || {};
801
+ eventTypeList.forEach((__eventType) => {
787
802
  let event: Event = null as any;
788
803
  if (details && details instanceof Event) {
789
804
  event = details;
790
805
  } else {
791
- event = new Event(_eventType_);
806
+ // 构造事件
807
+ event = new Event(__eventType);
792
808
  if (details) {
793
809
  Object.keys(details).forEach((keyName) => {
794
- (event as any)[keyName] = (details as any)[keyName];
810
+ const value = Reflect.get(details, keyName);
811
+ // 在event上添加属性
812
+ Reflect.set(event, keyName, value);
795
813
  });
796
814
  }
797
815
  }
798
- if (useDispatchToTriggerEvent == false && _eventType_ in events) {
799
- events[_eventType_].forEach((eventsItem: any) => {
816
+ if (useDispatchToTriggerEvent == false && __eventType in elementEvents) {
817
+ // 直接调用监听的事件
818
+ elementEvents[__eventType].forEach((eventsItem: any) => {
800
819
  eventsItem.callback(event);
801
820
  });
802
821
  } else {
803
- elementItem.dispatchEvent(event);
822
+ $elItem.dispatchEvent(event);
804
823
  }
805
824
  });
806
825
  });
@@ -826,24 +845,24 @@ export class DOMUtilsEvent {
826
845
  details?: any,
827
846
  useDispatchToTriggerEvent?: boolean
828
847
  ) {
829
- const DOMUtilsContext = this;
848
+ const that = this;
830
849
  if (typeof element === "string") {
831
- element = DOMUtilsContext.selectorAll(element);
850
+ element = that.selectorAll(element);
832
851
  }
833
852
  if (element == null) {
834
853
  return;
835
854
  }
836
- if (DOMUtilsCommonUtils.isNodeList(element)) {
855
+ if (CommonUtils.isNodeList(element)) {
837
856
  // 设置
838
857
  element.forEach(($ele) => {
839
- DOMUtilsContext.click($ele as HTMLElement, handler, details, useDispatchToTriggerEvent);
858
+ that.click($ele as HTMLElement, handler, details, useDispatchToTriggerEvent);
840
859
  });
841
860
  return;
842
861
  }
843
862
  if (handler == null) {
844
- DOMUtilsContext.trigger(element, "click", details, useDispatchToTriggerEvent);
863
+ that.trigger(element, "click", details, useDispatchToTriggerEvent);
845
864
  } else {
846
- DOMUtilsContext.on(element, "click", null, handler);
865
+ that.on(element, "click", null, handler);
847
866
  }
848
867
  }
849
868
  /**
@@ -866,24 +885,24 @@ export class DOMUtilsEvent {
866
885
  details?: object,
867
886
  useDispatchToTriggerEvent?: boolean
868
887
  ) {
869
- const DOMUtilsContext = this;
888
+ const that = this;
870
889
  if (typeof element === "string") {
871
- element = DOMUtilsContext.selectorAll(element);
890
+ element = that.selectorAll(element);
872
891
  }
873
892
  if (element == null) {
874
893
  return;
875
894
  }
876
- if (DOMUtilsCommonUtils.isNodeList(element)) {
895
+ if (CommonUtils.isNodeList(element)) {
877
896
  // 设置
878
897
  element.forEach(($ele) => {
879
- DOMUtilsContext.focus($ele as HTMLElement, handler, details, useDispatchToTriggerEvent);
898
+ that.focus($ele as HTMLElement, handler, details, useDispatchToTriggerEvent);
880
899
  });
881
900
  return;
882
901
  }
883
902
  if (handler === null) {
884
- DOMUtilsContext.trigger(element, "blur", details, useDispatchToTriggerEvent);
903
+ that.trigger(element, "blur", details, useDispatchToTriggerEvent);
885
904
  } else {
886
- DOMUtilsContext.on(element, "blur", null, handler as (event: Event) => void);
905
+ that.on(element, "blur", null, handler as (event: Event) => void);
887
906
  }
888
907
  }
889
908
  /**
@@ -906,24 +925,24 @@ export class DOMUtilsEvent {
906
925
  details?: object,
907
926
  useDispatchToTriggerEvent?: boolean
908
927
  ) {
909
- const DOMUtilsContext = this;
928
+ const that = this;
910
929
  if (typeof element === "string") {
911
- element = DOMUtilsContext.selectorAll(element);
930
+ element = that.selectorAll(element);
912
931
  }
913
932
  if (element == null) {
914
933
  return;
915
934
  }
916
- if (DOMUtilsCommonUtils.isNodeList(element)) {
935
+ if (CommonUtils.isNodeList(element)) {
917
936
  // 设置
918
937
  element.forEach(($ele) => {
919
- DOMUtilsContext.focus($ele as HTMLElement, handler, details, useDispatchToTriggerEvent);
938
+ that.focus($ele as HTMLElement, handler, details, useDispatchToTriggerEvent);
920
939
  });
921
940
  return;
922
941
  }
923
942
  if (handler == null) {
924
- DOMUtilsContext.trigger(element, "focus", details, useDispatchToTriggerEvent);
943
+ that.trigger(element, "focus", details, useDispatchToTriggerEvent);
925
944
  } else {
926
- DOMUtilsContext.on(element, "focus", null, handler);
945
+ that.on(element, "focus", null, handler);
927
946
  }
928
947
  }
929
948
  /**
@@ -945,22 +964,22 @@ export class DOMUtilsEvent {
945
964
  handler: (this: HTMLElement, event: DOMUtils_Event["hover"]) => void,
946
965
  option?: boolean | DOMUtilsEventListenerOption
947
966
  ) {
948
- const DOMUtilsContext = this;
967
+ const that = this;
949
968
  if (typeof element === "string") {
950
- element = DOMUtilsContext.selectorAll(element);
969
+ element = that.selectorAll(element);
951
970
  }
952
971
  if (element == null) {
953
972
  return;
954
973
  }
955
- if (DOMUtilsCommonUtils.isNodeList(element)) {
974
+ if (CommonUtils.isNodeList(element)) {
956
975
  // 设置
957
976
  element.forEach(($ele) => {
958
- DOMUtilsContext.hover($ele as HTMLElement, handler, option);
977
+ that.hover($ele as HTMLElement, handler, option);
959
978
  });
960
979
  return;
961
980
  }
962
- DOMUtilsContext.on(element, "mouseenter", null, handler, option);
963
- DOMUtilsContext.on(element, "mouseleave", null, handler, option);
981
+ that.on(element, "mouseenter", null, handler, option);
982
+ that.on(element, "mouseleave", null, handler, option);
964
983
  }
965
984
  /**
966
985
  * 当动画结束时触发事件
@@ -973,30 +992,23 @@ export class DOMUtilsEvent {
973
992
  handler: (this: HTMLElement, event: DOMUtils_Event["animationend"]) => void,
974
993
  option?: boolean | DOMUtilsEventListenerOption
975
994
  ) {
976
- const DOMUtilsContext = this;
995
+ const that = this;
977
996
  if (typeof element === "string") {
978
- element = DOMUtilsContext.selector(element)!;
997
+ element = that.selector(element)!;
979
998
  }
980
999
  if (element == null) {
981
1000
  return;
982
1001
  }
983
- // if (DOMUtilsCommonUtils.isNodeList(element)) {
984
- // // 设置
985
- // element.forEach(($ele) => {
986
- // DOMUtilsContext.animationend($ele as HTMLElement, handler, option);
987
- // });
988
- // return;
989
- // }
990
1002
  const defaultOption: DOMUtilsEventListenerOption = {
991
1003
  once: true,
992
1004
  };
993
1005
  Object.assign(defaultOption, option || {});
994
- const eventNameList = DOMUtilsCommonUtils.getAnimationEndNameList();
995
- DOMUtilsContext.on(element, eventNameList, null, handler, defaultOption);
1006
+ const eventNameList = CommonUtils.getAnimationEndNameList();
1007
+ that.on(element, eventNameList, null, handler, defaultOption);
996
1008
  if (!defaultOption.once) {
997
1009
  return {
998
1010
  off() {
999
- DOMUtilsContext.off(element, eventNameList, null, handler, defaultOption);
1011
+ that.off(element, eventNameList, null, handler, defaultOption);
1000
1012
  },
1001
1013
  };
1002
1014
  }
@@ -1012,30 +1024,23 @@ export class DOMUtilsEvent {
1012
1024
  handler: (this: HTMLElement, event: DOMUtils_Event["transitionend"]) => void,
1013
1025
  option?: boolean | DOMUtilsEventListenerOption
1014
1026
  ) {
1015
- const DOMUtilsContext = this;
1027
+ const that = this;
1016
1028
  if (typeof element === "string") {
1017
- element = DOMUtilsContext.selector(element)!;
1029
+ element = that.selector(element)!;
1018
1030
  }
1019
1031
  if (element == null) {
1020
1032
  return;
1021
1033
  }
1022
- // if (DOMUtilsCommonUtils.isNodeList(element)) {
1023
- // // 设置
1024
- // element.forEach(($ele) => {
1025
- // DOMUtilsContext.transitionend($ele as HTMLElement, handler, option);
1026
- // });
1027
- // return;
1028
- // }
1029
1034
  const defaultOption: DOMUtilsEventListenerOption = {
1030
1035
  once: true,
1031
1036
  };
1032
1037
  Object.assign(defaultOption, option || {});
1033
- const eventNameList = DOMUtilsCommonUtils.getTransitionEndNameList();
1034
- DOMUtilsContext.on(element, eventNameList, null, handler, defaultOption);
1038
+ const eventNameList = CommonUtils.getTransitionEndNameList();
1039
+ that.on(element, eventNameList, null, handler, defaultOption);
1035
1040
  if (!defaultOption.once) {
1036
1041
  return {
1037
1042
  off() {
1038
- DOMUtilsContext.off(element, eventNameList, null, handler, defaultOption);
1043
+ that.off(element, eventNameList, null, handler, defaultOption);
1039
1044
  },
1040
1045
  };
1041
1046
  }
@@ -1060,21 +1065,21 @@ export class DOMUtilsEvent {
1060
1065
  handler: (this: HTMLElement, event: DOMUtils_Event["keyup"]) => void,
1061
1066
  option?: boolean | DOMUtilsEventListenerOption
1062
1067
  ) {
1063
- const DOMUtilsContext = this;
1068
+ const that = this;
1064
1069
  if (element == null) {
1065
1070
  return;
1066
1071
  }
1067
1072
  if (typeof element === "string") {
1068
- element = DOMUtilsContext.selectorAll(element);
1073
+ element = that.selectorAll(element);
1069
1074
  }
1070
- if (DOMUtilsCommonUtils.isNodeList(element)) {
1075
+ if (CommonUtils.isNodeList(element)) {
1071
1076
  // 设置
1072
1077
  element.forEach(($ele) => {
1073
- DOMUtilsContext.keyup($ele as HTMLElement, handler, option);
1078
+ that.keyup($ele as HTMLElement, handler, option);
1074
1079
  });
1075
1080
  return;
1076
1081
  }
1077
- DOMUtilsContext.on(element, "keyup", null, handler, option);
1082
+ that.on(element, "keyup", null, handler, option);
1078
1083
  }
1079
1084
  /**
1080
1085
  * 当按键按下时触发事件
@@ -1096,21 +1101,21 @@ export class DOMUtilsEvent {
1096
1101
  handler: (this: HTMLElement, event: DOMUtils_Event["keydown"]) => void,
1097
1102
  option?: boolean | DOMUtilsEventListenerOption
1098
1103
  ) {
1099
- const DOMUtilsContext = this;
1104
+ const that = this;
1100
1105
  if (element == null) {
1101
1106
  return;
1102
1107
  }
1103
1108
  if (typeof element === "string") {
1104
- element = DOMUtilsContext.selectorAll(element);
1109
+ element = that.selectorAll(element);
1105
1110
  }
1106
- if (DOMUtilsCommonUtils.isNodeList(element)) {
1111
+ if (CommonUtils.isNodeList(element)) {
1107
1112
  // 设置
1108
1113
  element.forEach(($ele) => {
1109
- DOMUtilsContext.keydown($ele as HTMLElement, handler, option);
1114
+ that.keydown($ele as HTMLElement, handler, option);
1110
1115
  });
1111
1116
  return;
1112
1117
  }
1113
- DOMUtilsContext.on(element, "keydown", null, handler, option);
1118
+ that.on(element, "keydown", null, handler, option);
1114
1119
  }
1115
1120
  /**
1116
1121
  * 当按键按下时触发事件
@@ -1132,21 +1137,21 @@ export class DOMUtilsEvent {
1132
1137
  handler: (this: HTMLElement, event: DOMUtils_Event["keypress"]) => void,
1133
1138
  option?: boolean | DOMUtilsEventListenerOption
1134
1139
  ) {
1135
- const DOMUtilsContext = this;
1140
+ const that = this;
1136
1141
  if (element == null) {
1137
1142
  return;
1138
1143
  }
1139
1144
  if (typeof element === "string") {
1140
- element = DOMUtilsContext.selectorAll(element);
1145
+ element = that.selectorAll(element);
1141
1146
  }
1142
- if (DOMUtilsCommonUtils.isNodeList(element)) {
1147
+ if (CommonUtils.isNodeList(element)) {
1143
1148
  // 设置
1144
1149
  element.forEach(($ele) => {
1145
- DOMUtilsContext.keypress($ele as HTMLElement, handler, option);
1150
+ that.keypress($ele as HTMLElement, handler, option);
1146
1151
  });
1147
1152
  return;
1148
1153
  }
1149
- DOMUtilsContext.on(element, "keypress", null, handler, option);
1154
+ that.on(element, "keypress", null, handler, option);
1150
1155
  }
1151
1156
  /**
1152
1157
  * 监听某个元素键盘按键事件或window全局按键事件
@@ -1219,9 +1224,9 @@ export class DOMUtilsEvent {
1219
1224
  ): {
1220
1225
  removeListen(): void;
1221
1226
  } {
1222
- const DOMUtilsContext = this;
1227
+ const that = this;
1223
1228
  if (typeof element === "string") {
1224
- element = DOMUtilsContext.selectorAll(element);
1229
+ element = that.selectorAll(element);
1225
1230
  }
1226
1231
  const keyboardEventCallBack = function (event: KeyboardEvent) {
1227
1232
  /** 键名 */
@@ -1246,258 +1251,58 @@ export class DOMUtilsEvent {
1246
1251
  callback(keyName, keyValue, otherCodeList, event);
1247
1252
  }
1248
1253
  };
1249
- DOMUtilsContext.on(element, eventName, keyboardEventCallBack, options);
1254
+ that.on(element, eventName, keyboardEventCallBack, options);
1250
1255
  return {
1251
1256
  removeListen: () => {
1252
- DOMUtilsContext.off(element, eventName, keyboardEventCallBack, options);
1257
+ that.off(element, eventName, keyboardEventCallBack, options);
1253
1258
  },
1254
1259
  };
1255
1260
  }
1256
1261
  /**
1257
- * 选择器,可使用以下的额外语法
1258
- *
1259
- * + :contains([text]) 作用: 找到包含指定文本内容的指定元素
1260
- * + :empty 作用:找到既没有文本内容也没有子元素的指定元素
1261
- * + :regexp([text]) 作用: 找到符合正则表达式的内容的指定元素
1262
- * @param selector 选择器
1263
- * @param parent 指定父元素
1264
- * @example
1265
- * DOMUtils.selector("div:contains('测试')")
1266
- * > div.xxx
1262
+ * 阻止事件传递
1263
+ * @param event 要阻止传递的事件
1267
1264
  * @example
1268
- * DOMUtils.selector("div:empty")
1269
- * > div.xxx
1270
- * @example
1271
- * DOMUtils.selector("div:regexp('^xxxx$')")
1272
- * > div.xxx
1265
+ * DOMUtils.preventEvent(event);
1273
1266
  */
1274
- selector<K extends keyof HTMLElementTagNameMap>(
1275
- selector: K,
1276
- parent?: Element | Document | DocumentFragment | ShadowRoot
1277
- ): HTMLElementTagNameMap[K] | undefined;
1278
- selector<E extends Element = HTMLElement>(
1279
- selector: string,
1280
- parent?: Element | Document | DocumentFragment | ShadowRoot
1281
- ): E | undefined;
1282
- selector<E extends Element = HTMLElement>(
1283
- selector: string,
1284
- parent?: Element | Document | DocumentFragment | ShadowRoot
1285
- ) {
1286
- return this.selectorAll<E>(selector, parent)[0];
1287
- }
1267
+ preventEvent(event: Event): boolean;
1288
1268
  /**
1289
- * 选择器,可使用以下的额外语法
1290
- *
1291
- * + :contains([text]) 作用: 找到包含指定文本内容的指定元素
1292
- * + :empty 作用:找到既没有文本内容也没有子元素的指定元素
1293
- * + :regexp([text]) 作用: 找到符合正则表达式的内容的指定元素
1294
- * @param selector 选择器
1295
- * @param parent 指定父元素
1296
- * @example
1297
- * DOMUtils.selectorAll("div:contains('测试')")
1298
- * > [div.xxx]
1299
- * @example
1300
- * DOMUtils.selectorAll("div:empty")
1301
- * > [div.xxx]
1302
- * @example
1303
- * DOMUtils.selectorAll("div:regexp('^xxxx$')")
1304
- * > [div.xxx]
1269
+ * 通过监听事件来主动阻止事件的传递
1270
+ * @param $el 要进行处理的元素
1271
+ * @param eventNameList (可选)要阻止的事件名|列表
1272
+ * @param capture (可选)是否捕获,默认false
1305
1273
  * @example
1306
- * DOMUtils.selectorAll("div:regexp(/^xxx/ig)")
1307
- * > [div.xxx]
1274
+ * DOMUtils.preventEvent(document.querySelector("a"),"click")
1308
1275
  */
1309
- selectorAll<K extends keyof HTMLElementTagNameMap>(
1310
- selector: K,
1311
- parent?: Element | Document | DocumentFragment | ShadowRoot
1312
- ): HTMLElementTagNameMap[K][];
1313
- selectorAll<E extends Element = HTMLElement>(
1314
- selector: string,
1315
- parent?: Element | Document | DocumentFragment | ShadowRoot
1316
- ): E[];
1317
- selectorAll<E extends Element = HTMLElement>(
1318
- selector: string,
1319
- parent?: Element | Document | DocumentFragment | ShadowRoot
1320
- ) {
1321
- const context = this;
1322
- parent = parent || context.windowApi.document;
1323
- selector = selector.trim();
1324
- if (selector.match(/[^\s]{1}:empty$/gi)) {
1325
- // empty 语法
1326
- selector = selector.replace(/:empty$/gi, "");
1327
- return Array.from(parent.querySelectorAll<E>(selector)).filter(($ele) => {
1328
- return $ele?.innerHTML?.trim() === "";
1329
- });
1330
- } else if (selector.match(/[^\s]{1}:contains\("(.*)"\)$/i) || selector.match(/[^\s]{1}:contains\('(.*)'\)$/i)) {
1331
- // contains 语法
1332
- const textMatch = selector.match(/:contains\(("|')(.*)("|')\)$/i);
1333
- const text = textMatch![2];
1334
- selector = selector.replace(/:contains\(("|')(.*)("|')\)$/gi, "");
1335
- return Array.from(parent.querySelectorAll<E>(selector)).filter(($ele) => {
1336
- // @ts-ignore
1337
- return ($ele?.textContent || $ele?.innerText)?.includes(text);
1338
- });
1339
- } else if (selector.match(/[^\s]{1}:regexp\("(.*)"\)$/i) || selector.match(/[^\s]{1}:regexp\('(.*)'\)$/i)) {
1340
- // regexp 语法
1341
- const textMatch = selector.match(/:regexp\(("|')(.*)("|')\)$/i);
1342
- let pattern = textMatch![2];
1343
- const flagMatch = pattern.match(/("|'),[\s]*("|')([igm]{0,3})$/i);
1344
- let flags = "";
1345
- if (flagMatch) {
1346
- pattern = pattern.replace(/("|'),[\s]*("|')([igm]{0,3})$/gi, "");
1347
- flags = flagMatch[3];
1348
- }
1349
- const regexp = new RegExp(pattern, flags);
1350
- selector = selector.replace(/:regexp\(("|')(.*)("|')\)$/gi, "");
1351
- return Array.from(parent.querySelectorAll<E>(selector)).filter(($ele) => {
1352
- // @ts-ignore
1353
- return Boolean(($ele?.textContent || $ele?.innerText)?.match(regexp));
1354
- });
1355
- } else {
1356
- // 普通语法
1357
- return Array.from(parent.querySelectorAll<E>(selector));
1358
- }
1359
- }
1360
- /**
1361
- * 匹配元素,可使用以下的额外语法
1362
- *
1363
- * + :contains([text]) 作用: 找到包含指定文本内容的指定元素
1364
- * + :empty 作用:找到既没有文本内容也没有子元素的指定元素
1365
- * + :regexp([text]) 作用: 找到符合正则表达式的内容的指定元素
1366
- * @param $el 元素
1367
- * @param selector 选择器
1368
- * @example
1369
- * DOMUtils.matches("div:contains('测试')")
1370
- * > true
1371
- * @example
1372
- * DOMUtils.matches("div:empty")
1373
- * > true
1374
- * @example
1375
- * DOMUtils.matches("div:regexp('^xxxx$')")
1376
- * > true
1377
- * @example
1378
- * DOMUtils.matches("div:regexp(/^xxx/ig)")
1379
- * > false
1380
- */
1381
- matches($el: HTMLElement | Element | null | undefined, selector: string): boolean {
1382
- selector = selector.trim();
1383
- if ($el == null) {
1276
+ preventEvent($el: HTMLElement, eventNameList?: string | string[], capture?: boolean): void;
1277
+ preventEvent(...args: any[]) {
1278
+ /**
1279
+ * 阻止事件的默认行为发生,并阻止事件传播
1280
+ */
1281
+ const stopEvent = (event: Event) => {
1282
+ /* 阻止事件的默认行为发生。例如,当点击一个链接时,浏览器会默认打开链接的URL */
1283
+ event?.preventDefault();
1284
+ /* 停止事件的传播,阻止它继续向更上层的元素冒泡,事件将不会再传播给其他的元素 */
1285
+ event?.stopPropagation();
1286
+ /* 阻止事件传播,并且还能阻止元素上的其他事件处理程序被触发 */
1287
+ event?.stopImmediatePropagation();
1384
1288
  return false;
1385
- }
1386
-
1387
- if (selector.match(/[^\s]{1}:empty$/gi)) {
1388
- // empty 语法
1389
- selector = selector.replace(/:empty$/gi, "");
1390
- return $el.matches(selector) && $el?.innerHTML?.trim() === "";
1391
- } else if (selector.match(/[^\s]{1}:contains\("(.*)"\)$/i) || selector.match(/[^\s]{1}:contains\('(.*)'\)$/i)) {
1392
- // contains 语法
1393
- const textMatch = selector.match(/:contains\(("|')(.*)("|')\)$/i);
1394
- const text = textMatch![2];
1395
- selector = selector.replace(/:contains\(("|')(.*)("|')\)$/gi, "");
1396
- // @ts-ignore
1397
- let content = $el?.textContent || $el?.innerText;
1398
- if (typeof content !== "string") {
1399
- content = "";
1400
- }
1401
- return $el.matches(selector) && content?.includes(text);
1402
- } else if (selector.match(/[^\s]{1}:regexp\("(.*)"\)$/i) || selector.match(/[^\s]{1}:regexp\('(.*)'\)$/i)) {
1403
- // regexp 语法
1404
- const textMatch = selector.match(/:regexp\(("|')(.*)("|')\)$/i);
1405
- let pattern = textMatch![2];
1406
- const flagMatch = pattern.match(/("|'),[\s]*("|')([igm]{0,3})$/i);
1407
- let flags = "";
1408
- if (flagMatch) {
1409
- pattern = pattern.replace(/("|'),[\s]*("|')([igm]{0,3})$/gi, "");
1410
- flags = flagMatch[3];
1411
- }
1412
- const regexp = new RegExp(pattern, flags);
1413
- selector = selector.replace(/:regexp\(("|')(.*)("|')\)$/gi, "");
1414
- // @ts-ignore
1415
- let content = $el?.textContent || $el?.innerText;
1416
- if (typeof content !== "string") {
1417
- content = "";
1418
- }
1419
- return $el.matches(selector) && Boolean(content?.match(regexp));
1289
+ };
1290
+ if (args.length === 1) {
1291
+ /* 直接阻止事件 */
1292
+ return stopEvent(args[0]);
1420
1293
  } else {
1421
- // 普通语法
1422
- return $el.matches(selector);
1423
- }
1424
- }
1425
- /**
1426
- * 根据选择器获取上层元素,可使用以下的额外语法
1427
- *
1428
- * + :contains([text]) 作用: 找到包含指定文本内容的指定元素
1429
- * + :empty 作用:找到既没有文本内容也没有子元素的指定元素
1430
- * + :regexp([text]) 作用: 找到符合正则表达式的内容的指定元素
1431
- * @param $el 元素
1432
- * @param selector 选择器
1433
- * @example
1434
- * DOMUtils.closest("div:contains('测试')")
1435
- * > div.xxx
1436
- * @example
1437
- * DOMUtils.closest("div:empty")
1438
- * > div.xxx
1439
- * @example
1440
- * DOMUtils.closest("div:regexp('^xxxx$')")
1441
- * > div.xxxx
1442
- * @example
1443
- * DOMUtils.closest("div:regexp(/^xxx/ig)")
1444
- * > null
1445
- */
1446
- closest<K extends keyof HTMLElementTagNameMap>(
1447
- $el: HTMLElement | Element,
1448
- selector: string
1449
- ): HTMLElementTagNameMap[K] | null;
1450
- closest<E extends Element = Element>($el: HTMLElement | Element, selector: string): E | null;
1451
- closest<E extends Element = Element>($el: HTMLElement | Element, selector: string): E | null {
1452
- selector = selector.trim();
1453
-
1454
- if (selector.match(/[^\s]{1}:empty$/gi)) {
1455
- // empty 语法
1456
- selector = selector.replace(/:empty$/gi, "");
1457
- const $closest = $el?.closest<E>(selector);
1458
- if ($closest && $closest?.innerHTML?.trim() === "") {
1459
- return $closest;
1294
+ const $el: HTMLElement = args[0];
1295
+ let eventNameList: string | string[] = args[1];
1296
+ const capture: boolean = args[2];
1297
+ /* 添加对应的事件来阻止触发 */
1298
+ if (typeof eventNameList === "string") {
1299
+ eventNameList = [eventNameList];
1460
1300
  }
1461
- return null;
1462
- } else if (selector.match(/[^\s]{1}:contains\("(.*)"\)$/i) || selector.match(/[^\s]{1}:contains\('(.*)'\)$/i)) {
1463
- // contains 语法
1464
- const textMatch = selector.match(/:contains\(("|')(.*)("|')\)$/i);
1465
- const text = textMatch![2];
1466
- selector = selector.replace(/:contains\(("|')(.*)("|')\)$/gi, "");
1467
- const $closest = $el?.closest<E>(selector);
1468
- if ($closest) {
1469
- // @ts-ignore
1470
- const content = $el?.textContent || $el?.innerText;
1471
- if (typeof content === "string" && content.includes(text)) {
1472
- return $closest;
1473
- }
1474
- }
1475
- return null;
1476
- } else if (selector.match(/[^\s]{1}:regexp\("(.*)"\)$/i) || selector.match(/[^\s]{1}:regexp\('(.*)'\)$/i)) {
1477
- // regexp 语法
1478
- const textMatch = selector.match(/:regexp\(("|')(.*)("|')\)$/i);
1479
- let pattern = textMatch![2];
1480
- const flagMatch = pattern.match(/("|'),[\s]*("|')([igm]{0,3})$/i);
1481
- let flags = "";
1482
- if (flagMatch) {
1483
- pattern = pattern.replace(/("|'),[\s]*("|')([igm]{0,3})$/gi, "");
1484
- flags = flagMatch[3];
1485
- }
1486
- const regexp = new RegExp(pattern, flags);
1487
- selector = selector.replace(/:regexp\(("|')(.*)("|')\)$/gi, "");
1488
- const $closest = $el?.closest<E>(selector);
1489
- if ($closest) {
1490
- // @ts-ignore
1491
- const content = $el?.textContent || $el?.innerText;
1492
- if (typeof content === "string" && content.match(regexp)) {
1493
- return $closest;
1494
- }
1495
- }
1496
- return null;
1497
- } else {
1498
- // 普通语法
1499
- const $closest = $el?.closest<E>(selector);
1500
- return $closest;
1301
+ this.on($el, eventNameList, stopEvent, { capture: Boolean(capture) });
1501
1302
  }
1502
1303
  }
1503
1304
  }
1305
+
1306
+ const elementEvent = new ElementEvent();
1307
+
1308
+ export { elementEvent, ElementEvent };