@whitesev/domutils 1.9.5 → 1.9.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.
@@ -830,20 +830,23 @@ class ElementEvent extends ElementAnimate {
830
830
  /**
831
831
  * 主动触发事件
832
832
  * @param element 需要触发的元素|元素数组|window
833
- * @param eventType 需要触发的事件
834
- * @param extraDetails 赋予触发的Event的额外属性,如果是Event类型,那么将自动代替默认new的Event对象
835
- * @param useDispatchToTriggerEvent 是否使用dispatchEvent来触发事件,默认true,如果为false,则直接调用通过.on监听的callback(),但是这种只有一个入参,如果使用$selector则没有值
833
+ * @param event 触发的事件
834
+ * @param extraDetails (可选)赋予触发的Event的额外属性
835
+ * @param useDispatchToTriggerEvent (可选)是否使用dispatchEvent来触发事件,默认true,如果为false,则直接调用通过.on监听的callback(),但是这种只有一个入参,如果使用$selector则没有值
836
836
  * @example
837
- * // 触发元素a.xxclick事件
838
- * DOMUtils.emit(document.querySelector("a.xx"),"click")
839
- * DOMUtils.emit("a.xx","click")
840
- * // 触发元素a.xx的click、tap、hover事件
841
- * DOMUtils.emit(document.querySelector("a.xx"),"click tap hover")
842
- * DOMUtils.emit("a.xx",["click","tap","hover"])
837
+ * DOMUtils.emit("a.xx", new Event("click"))
838
+ * @example
839
+ * DOMUtils.emit("a.xx", new Event("click"), {
840
+ * disableHook: true
841
+ * })
842
+ * @example
843
+ * DOMUtils.emit("a.xx", new Event("click"), {
844
+ * disableHook: true
845
+ * },false)
843
846
  */
844
847
  emit(
845
848
  element: Element | string | NodeList | any[] | Window | Document,
846
- eventType: DOMUtils_EventType | DOMUtils_EventType[],
849
+ event: Event,
847
850
  extraDetails?: object,
848
851
  useDispatchToTriggerEvent?: boolean
849
852
  ): void;
@@ -863,7 +866,7 @@ class ElementEvent extends ElementAnimate {
863
866
  */
864
867
  emit(
865
868
  element: Element | string | NodeList | any[] | Window | Document,
866
- eventType: DOMUtils_EventType | DOMUtils_EventType[] | string | string[],
869
+ eventType: DOMUtils_EventType | DOMUtils_EventType[] | string | string[] | Event,
867
870
  extraDetails?: object | boolean,
868
871
  useDispatchToTriggerEvent: boolean = true
869
872
  ) {
@@ -880,11 +883,33 @@ class ElementEvent extends ElementAnimate {
880
883
  } else {
881
884
  $elList.push(element);
882
885
  }
886
+
887
+ /**
888
+ * 主动添加属性
889
+ */
890
+ const addExtraProp = (event: Event, obj: any) => {
891
+ if (event instanceof Event && typeof obj === "object" && obj != null && !Array.isArray(obj)) {
892
+ const detailKeys = Object.keys(obj);
893
+ detailKeys.forEach((keyName) => {
894
+ const value = Reflect.get(obj, keyName);
895
+ // 在event上添加属性
896
+ Reflect.set(event, keyName, value);
897
+ });
898
+ }
899
+ };
900
+
883
901
  let eventTypeList: string[] = [];
902
+ /**
903
+ * 主动传递的事件
904
+ */
905
+ let __event__: Event | null = null;
884
906
  if (Array.isArray(eventType)) {
885
907
  eventTypeList = eventType.filter((it) => typeof it === "string" && it.trim() !== "");
886
908
  } else if (typeof eventType === "string") {
887
909
  eventTypeList = eventType.split(" ");
910
+ } else if (eventType instanceof Event) {
911
+ __event__ = eventType;
912
+ addExtraProp(__event__, extraDetails);
888
913
  }
889
914
 
890
915
  $elList.forEach(($elItem) => {
@@ -892,31 +917,34 @@ class ElementEvent extends ElementAnimate {
892
917
  const elementEvents: {
893
918
  [key: string]: DOMUtilsEventListenerOptionsAttribute[];
894
919
  } = Reflect.get($elItem, GlobalData.domEventSymbol) || {};
895
- eventTypeList.forEach((eventTypeItem) => {
896
- let event: Event = null as any;
897
- if (extraDetails && extraDetails instanceof Event) {
898
- event = extraDetails;
899
- } else {
900
- // 构造事件
901
- event = new Event(eventTypeItem);
902
- if (typeof extraDetails === "object" && extraDetails != null) {
903
- const detailKeys = Object.keys(extraDetails);
904
- detailKeys.forEach((keyName) => {
905
- const value = Reflect.get(extraDetails, keyName);
906
- // 在event上添加属性
907
- Reflect.set(event, keyName, value);
908
- });
909
- }
910
- }
920
+
921
+ /**
922
+ * 触发事件
923
+ */
924
+ const dispatchEvent = (event: Event, eventTypeItem: string) => {
911
925
  if (useDispatchToTriggerEvent == false && eventTypeItem in elementEvents) {
912
- // 直接调用监听的事件
926
+ // 直接调用.on监听的事件
913
927
  elementEvents[eventTypeItem].forEach((eventsItem) => {
914
928
  eventsItem.handlerCallBack(event);
915
929
  });
916
930
  } else {
917
931
  $elItem.dispatchEvent(event);
918
932
  }
919
- });
933
+ };
934
+
935
+ if (__event__) {
936
+ // 使用主动传递的事件直接触发
937
+ const event = __event__;
938
+ const eventTypeItem = event.type;
939
+ dispatchEvent(event, eventTypeItem);
940
+ } else {
941
+ eventTypeList.forEach((eventTypeItem) => {
942
+ // 构造事件
943
+ const event = new Event(eventTypeItem);
944
+ addExtraProp(event, extraDetails);
945
+ dispatchEvent(event, eventTypeItem);
946
+ });
947
+ }
920
948
  });
921
949
  }
922
950
 
@@ -957,7 +985,8 @@ class ElementEvent extends ElementAnimate {
957
985
  if (handler == null) {
958
986
  that.emit(element, "click", details, useDispatchToEmit);
959
987
  } else {
960
- that.on(element, "click", null, handler);
988
+ const listener = that.on(element, "click", null, handler);
989
+ return listener;
961
990
  }
962
991
  }
963
992
  /**
@@ -997,7 +1026,8 @@ class ElementEvent extends ElementAnimate {
997
1026
  if (handler === null) {
998
1027
  that.emit(element, "blur", details, useDispatchToEmit);
999
1028
  } else {
1000
- that.on(element, "blur", null, handler as (event: Event) => void);
1029
+ const listener = that.on(element, "blur", null, handler as (event: Event) => void);
1030
+ return listener;
1001
1031
  }
1002
1032
  }
1003
1033
  /**
@@ -1037,7 +1067,8 @@ class ElementEvent extends ElementAnimate {
1037
1067
  if (handler == null) {
1038
1068
  that.emit(element, "focus", details, useDispatchToEmit);
1039
1069
  } else {
1040
- that.on(element, "focus", null, handler);
1070
+ const listener = that.on(element, "focus", null, handler);
1071
+ return listener;
1041
1072
  }
1042
1073
  }
1043
1074
  /**
@@ -1068,13 +1099,31 @@ class ElementEvent extends ElementAnimate {
1068
1099
  }
1069
1100
  if (CommonUtils.isNodeList(element)) {
1070
1101
  // 设置
1102
+ const listenerList: (DOMUtilsAddEventListenerResult | undefined)[] = [];
1071
1103
  element.forEach(($ele) => {
1072
- that.onHover($ele as HTMLElement, handler, option);
1104
+ const listener = that.onHover($ele as HTMLElement, handler, option);
1105
+ listenerList.push(listener);
1073
1106
  });
1074
- return;
1107
+ return {
1108
+ off() {
1109
+ listenerList.forEach((listener) => {
1110
+ if (!listener) {
1111
+ return;
1112
+ }
1113
+ listener.off();
1114
+ });
1115
+ },
1116
+ } as DOMUtilsAddEventListenerResult;
1075
1117
  }
1076
- that.on(element, "mouseenter", null, handler, option);
1077
- that.on(element, "mouseleave", null, handler, option);
1118
+ const mouseenter_listener = that.on(element, "mouseenter", null, handler, option);
1119
+ const mouseleave_listener = that.on(element, "mouseleave", null, handler, option);
1120
+
1121
+ return {
1122
+ off() {
1123
+ mouseenter_listener.off();
1124
+ mouseleave_listener.off();
1125
+ },
1126
+ } as DOMUtilsAddEventListenerResult;
1078
1127
  }
1079
1128
  /**
1080
1129
  * 监听动画结束
@@ -1169,12 +1218,23 @@ class ElementEvent extends ElementAnimate {
1169
1218
  }
1170
1219
  if (CommonUtils.isNodeList(element)) {
1171
1220
  // 设置
1221
+ const listenerList: (DOMUtilsAddEventListenerResult | undefined)[] = [];
1172
1222
  element.forEach(($ele) => {
1173
- that.onKeyup($ele as HTMLElement, handler, option);
1223
+ const listener = that.onKeyup($ele as HTMLElement, handler, option);
1224
+ listenerList.push(listener);
1174
1225
  });
1175
- return;
1226
+ return {
1227
+ off() {
1228
+ listenerList.forEach((listener) => {
1229
+ if (!listener) {
1230
+ return;
1231
+ }
1232
+ listener.off();
1233
+ });
1234
+ },
1235
+ } as DOMUtilsAddEventListenerResult;
1176
1236
  }
1177
- that.on(element, "keyup", null, handler, option);
1237
+ return that.on(element, "keyup", null, handler, option);
1178
1238
  }
1179
1239
  /**
1180
1240
  * 当按键按下时触发事件
@@ -1205,12 +1265,23 @@ class ElementEvent extends ElementAnimate {
1205
1265
  }
1206
1266
  if (CommonUtils.isNodeList(element)) {
1207
1267
  // 设置
1268
+ const listenerList: (DOMUtilsAddEventListenerResult | undefined)[] = [];
1208
1269
  element.forEach(($ele) => {
1209
- that.onKeydown($ele as HTMLElement, handler, option);
1270
+ const listener = that.onKeydown($ele as HTMLElement, handler, option);
1271
+ listenerList.push(listener);
1210
1272
  });
1211
- return;
1273
+ return {
1274
+ off() {
1275
+ listenerList.forEach((listener) => {
1276
+ if (!listener) {
1277
+ return;
1278
+ }
1279
+ listener.off();
1280
+ });
1281
+ },
1282
+ } as DOMUtilsAddEventListenerResult;
1212
1283
  }
1213
- that.on(element, "keydown", null, handler, option);
1284
+ return that.on(element, "keydown", null, handler, option);
1214
1285
  }
1215
1286
  /**
1216
1287
  * 当按键按下时触发事件
@@ -1241,12 +1312,23 @@ class ElementEvent extends ElementAnimate {
1241
1312
  }
1242
1313
  if (CommonUtils.isNodeList(element)) {
1243
1314
  // 设置
1315
+ const listenerList: (DOMUtilsAddEventListenerResult | undefined)[] = [];
1244
1316
  element.forEach(($ele) => {
1245
- that.onKeypress($ele as HTMLElement, handler, option);
1317
+ const listener = that.onKeypress($ele as HTMLElement, handler, option);
1318
+ listenerList.push(listener);
1246
1319
  });
1247
- return;
1320
+ return {
1321
+ off() {
1322
+ listenerList.forEach((listener) => {
1323
+ if (!listener) {
1324
+ return;
1325
+ }
1326
+ listener.off();
1327
+ });
1328
+ },
1329
+ } as DOMUtilsAddEventListenerResult;
1248
1330
  }
1249
- that.on(element, "keypress", null, handler, option);
1331
+ return that.on(element, "keypress", null, handler, option);
1250
1332
  }
1251
1333
  /**
1252
1334
  * 监听某个元素键盘按键事件或window全局按键事件
@@ -1316,9 +1398,7 @@ class ElementEvent extends ElementAnimate {
1316
1398
  eventName: "keydown" | "keypress" | "keyup" = "keypress",
1317
1399
  handler: (keyName: string, keyValue: number, otherCodeList: string[], event: KeyboardEvent) => void,
1318
1400
  options?: DOMUtilsEventListenerOption | boolean
1319
- ): {
1320
- removeListen(): void;
1321
- } {
1401
+ ): DOMUtilsAddEventListenerResult {
1322
1402
  const that = this;
1323
1403
  if (typeof element === "string") {
1324
1404
  element = that.selectorAll(element);
@@ -1346,12 +1426,8 @@ class ElementEvent extends ElementAnimate {
1346
1426
  handler(keyName, keyValue, otherCodeList, event);
1347
1427
  }
1348
1428
  };
1349
- that.on(element, eventName, keyboardEventCallBack, options);
1350
- return {
1351
- removeListen: () => {
1352
- that.off(element, eventName, keyboardEventCallBack, options);
1353
- },
1354
- };
1429
+ const listener = that.on(element, eventName, keyboardEventCallBack, options);
1430
+ return listener;
1355
1431
  }
1356
1432
  /**
1357
1433
  * 监input、textarea的输入框值改变的事件(当输入法输入时,不会触发该监听)
@@ -1363,7 +1439,7 @@ class ElementEvent extends ElementAnimate {
1363
1439
  $el: HTMLInputElement | HTMLTextAreaElement,
1364
1440
  handler: (evt: InputEvent) => void | Promise<void>,
1365
1441
  option?: DOMUtilsEventListenerOption | boolean
1366
- ) {
1442
+ ): DOMUtilsAddEventListenerResult {
1367
1443
  /**
1368
1444
  * 是否正在输入中
1369
1445
  */
@@ -1386,11 +1462,14 @@ class ElementEvent extends ElementAnimate {
1386
1462
  const compositionEndListener = this.on($el, "compositionend", __composition_end_callback, option);
1387
1463
 
1388
1464
  return {
1389
- off: () => {
1465
+ off() {
1390
1466
  inputListener.off();
1391
1467
  compositionStartListener.off();
1392
1468
  compositionEndListener.off();
1393
1469
  },
1470
+ emit(details?, useDispatchToEmit?) {
1471
+ inputListener.emit(details, useDispatchToEmit);
1472
+ },
1394
1473
  };
1395
1474
  }
1396
1475
  /**
@@ -1520,45 +1599,149 @@ class ElementEvent extends ElementAnimate {
1520
1599
  }
1521
1600
  /**
1522
1601
  * 阻止事件传递
1602
+ *
1603
+ * + `.preventDefault()`: 阻止事件的默认行为发生。例如,当点击一个链接时,浏览器会默认打开链接的URL,或者在输入框内输入文字
1604
+ * + `.stopPropagation()`: 停止事件的传播,阻止它继续向更上层的元素冒泡,事件将不会再传播给其他的元素
1605
+ * + `.stopImmediatePropagation()`: 阻止事件传播,并且还能阻止元素上的其他事件处理程序被触发
1523
1606
  * @param event 要阻止传递的事件
1524
1607
  * @example
1525
1608
  * DOMUtils.preventEvent(event);
1526
1609
  */
1527
- preventEvent(event: Event): boolean;
1610
+ preventEvent(event: Event): false;
1611
+ /**
1612
+ * 阻止事件传递
1613
+ * @param event 要阻止传递的事件
1614
+ * @param onlyStopPropagation (可选)是否仅阻止事件的传播,默认false,不调用`.preventDefault()`
1615
+ * @example
1616
+ * DOMUtils.preventEvent(event, true);
1617
+ */
1618
+ preventEvent<T extends boolean>(event: Event, onlyStopPropagation: T): T extends true ? void : false;
1619
+ /**
1620
+ * 通过监听事件来主动阻止事件的传递
1621
+ * @param $el 要进行处理的元素
1622
+ * @param eventNameList 要阻止的事件名|列表
1623
+ * @param option (可选)配置项
1624
+ * @example
1625
+ * DOMUtils.preventEvent(document.querySelector("a"), "click")
1626
+ * @example
1627
+ * DOMUtils.preventEvent(document.querySelector("a"), "click", undefined, {
1628
+ * capture: true,
1629
+ * })
1630
+ * @example
1631
+ * DOMUtils.preventEvent(document, "click", "a.xxx", {
1632
+ * capture: true,
1633
+ * onlyStopPropagation: true,
1634
+ * })
1635
+ */
1636
+ preventEvent(
1637
+ $el: HTMLElement,
1638
+ eventNameList: string | string[],
1639
+ option?: {
1640
+ /** (可选)是否捕获,默认false */
1641
+ capture?: boolean;
1642
+ /** (可选)是否仅阻止事件的传播,默认false,不调用`.preventDefault()` */
1643
+ onlyStopPropagation?: boolean;
1644
+ }
1645
+ ): {
1646
+ /** 移除监听事件 */
1647
+ off(): void;
1648
+ };
1528
1649
  /**
1529
1650
  * 通过监听事件来主动阻止事件的传递
1530
1651
  * @param $el 要进行处理的元素
1531
- * @param eventNameList (可选)要阻止的事件名|列表
1532
- * @param capture (可选)是否捕获,默认false
1652
+ * @param eventNameList 要阻止的事件名|列表
1653
+ * @param selector 子元素选择器
1654
+ * @param option (可选)配置项
1655
+ * @example
1656
+ * DOMUtils.preventEvent(document.querySelector("a"), "click")
1657
+ * @example
1658
+ * DOMUtils.preventEvent(document.querySelector("a"), "click", undefined, {
1659
+ * capture: true,
1660
+ * })
1533
1661
  * @example
1534
- * DOMUtils.preventEvent(document.querySelector("a"),"click")
1662
+ * DOMUtils.preventEvent(document, "click", "a.xxx", {
1663
+ * capture: true,
1664
+ * onlyStopPropagation: true,
1665
+ * })
1535
1666
  */
1536
- preventEvent($el: HTMLElement, eventNameList?: string | string[], capture?: boolean): void;
1537
- preventEvent(...args: any[]) {
1667
+ preventEvent(
1668
+ $el: HTMLElement,
1669
+ eventNameList: string | string[],
1670
+ selector: string | string[] | null | undefined,
1671
+ option?: {
1672
+ /** (可选)是否捕获,默认false */
1673
+ capture?: boolean;
1674
+ /** (可选)是否仅阻止事件的传播,默认false,不调用`.preventDefault()` */
1675
+ onlyStopPropagation?: boolean;
1676
+ }
1677
+ ): {
1678
+ /** 移除监听事件 */
1679
+ off(): void;
1680
+ };
1681
+ preventEvent(...args: any[]): boolean | void | { off(): void } {
1538
1682
  /**
1539
1683
  * 阻止事件的默认行为发生,并阻止事件传播
1540
1684
  */
1541
- const stopEvent = (event: Event) => {
1542
- /* 阻止事件的默认行为发生。例如,当点击一个链接时,浏览器会默认打开链接的URL */
1685
+ const stopEvent = (event: Event, onlyStopPropagation?: boolean) => {
1686
+ if (typeof onlyStopPropagation === "boolean" && onlyStopPropagation) {
1687
+ // 停止事件的传播,阻止它继续向更上层的元素冒泡,事件将不会再传播给其他的元素
1688
+ event?.stopPropagation();
1689
+ // 阻止事件传播,并且还能阻止元素上的其他事件处理程序被触发
1690
+ event?.stopImmediatePropagation();
1691
+ return;
1692
+ }
1693
+ // 阻止事件的默认行为发生。例如,当点击一个链接时,浏览器会默认打开链接的URL,或者在输入框内输入文字
1543
1694
  event?.preventDefault();
1544
- /* 停止事件的传播,阻止它继续向更上层的元素冒泡,事件将不会再传播给其他的元素 */
1545
- event?.stopPropagation();
1546
- /* 阻止事件传播,并且还能阻止元素上的其他事件处理程序被触发 */
1547
- event?.stopImmediatePropagation();
1548
1695
  return false;
1549
1696
  };
1550
- if (args.length === 1) {
1551
- /* 直接阻止事件 */
1552
- return stopEvent(args[0]);
1697
+ if (args[0] instanceof Event) {
1698
+ // 直接阻止事件
1699
+ const onlyStopPropagation: boolean = args[1];
1700
+ return stopEvent(args[0], onlyStopPropagation);
1553
1701
  } else {
1554
1702
  const $el: HTMLElement = args[0];
1555
1703
  let eventNameList: string | string[] = args[1];
1556
- const capture: boolean = args[2];
1557
- /* 添加对应的事件来阻止触发 */
1704
+ let selector: string | string[] | null | undefined = void 0;
1705
+ let capture = false;
1706
+ let onlyStopPropagation = false;
1707
+ // 添加对应的事件来阻止触发
1558
1708
  if (typeof eventNameList === "string") {
1559
1709
  eventNameList = [eventNameList];
1560
1710
  }
1561
- this.on($el, eventNameList, stopEvent, { capture: Boolean(capture) });
1711
+
1712
+ let option:
1713
+ | {
1714
+ capture?: boolean;
1715
+ onlyStopPropagation?: boolean;
1716
+ }
1717
+ | undefined = void 0;
1718
+ if (typeof args[2] === "string" || Array.isArray(args[2])) {
1719
+ // selector
1720
+ selector = args[2];
1721
+ if (typeof args[3] === "object" && args[3] != null) {
1722
+ option = args[3];
1723
+ }
1724
+ } else if (typeof args[2] === "object" && args[2] != null && !Array.isArray(args[2])) {
1725
+ // option
1726
+ option = args[2];
1727
+ } else {
1728
+ throw new TypeError("Invalid argument");
1729
+ }
1730
+ if (option) {
1731
+ capture = Boolean(option.capture);
1732
+ onlyStopPropagation = Boolean(option.onlyStopPropagation);
1733
+ }
1734
+
1735
+ const listener = this.on(
1736
+ $el,
1737
+ eventNameList,
1738
+ selector,
1739
+ (evt) => {
1740
+ return stopEvent(evt, onlyStopPropagation);
1741
+ },
1742
+ { capture: capture }
1743
+ );
1744
+ return listener;
1562
1745
  }
1563
1746
  }
1564
1747
  }
package/src/Utils.ts CHANGED
@@ -156,10 +156,7 @@ class Utils {
156
156
  "slideDown",
157
157
  "slideToggle",
158
158
  "slideUp",
159
- "sort",
160
- "splice",
161
159
  "text",
162
- "toArray",
163
160
  "toggle",
164
161
  "toggleClass",
165
162
  "trigger",