@whitesev/domutils 1.9.11 → 2.0.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.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "@whitesev/domutils",
4
- "version": "1.9.11",
4
+ "version": "2.0.0",
5
5
  "description": "适合在浏览器中操作DOM的常用工具类",
6
6
  "keywords": [
7
7
  "typescript",
@@ -32,26 +32,26 @@
32
32
  "registry": "https://registry.npmjs.org/"
33
33
  },
34
34
  "devDependencies": {
35
- "@eslint/js": "^9.39.2",
36
- "@rollup/plugin-commonjs": "^29.0.1",
35
+ "@eslint/js": "^10.0.1",
36
+ "@rollup/plugin-commonjs": "^29.0.2",
37
37
  "@rollup/plugin-json": "^6.1.0",
38
38
  "@rollup/plugin-node-resolve": "^16.0.3",
39
- "@rollup/plugin-terser": "^0.4.4",
39
+ "@rollup/plugin-terser": "^1.0.0",
40
40
  "@rollup/plugin-typescript": "^12.3.0",
41
41
  "browserslist": "^4.28.1",
42
- "caniuse-lite": "^1.0.30001776",
43
- "eslint": "^9.39.2",
42
+ "caniuse-lite": "^1.0.30001782",
43
+ "eslint": "^10.1.0",
44
44
  "eslint-config-prettier": "^10.1.8",
45
- "eslint-plugin-compat": "^6.0.2",
45
+ "eslint-plugin-compat": "^7.0.1",
46
46
  "eslint-plugin-prettier": "^5.5.5",
47
- "globals": "^16.5.0",
48
- "oxfmt": "^0.36.0",
49
- "oxlint": "1.51.0",
50
- "rollup": "^4.54.0",
47
+ "globals": "^17.4.0",
48
+ "oxfmt": "^0.42.0",
49
+ "oxlint": "1.57.0",
50
+ "rollup": "^4.60.1",
51
51
  "rollup-plugin-clear": "^2.0.7",
52
52
  "tslib": "^2.8.1",
53
- "typescript": "^5.9.3",
54
- "typescript-eslint": "^8.50.1"
53
+ "typescript": "^6.0.2",
54
+ "typescript-eslint": "^8.58.0"
55
55
  },
56
56
  "scripts": {
57
57
  "lint": "oxlint .",
@@ -1,14 +1,14 @@
1
1
  import { CommonUtils } from "./CommonUtils";
2
2
  import { ElementAnimate } from "./ElementAnimate";
3
3
  import { GlobalData } from "./GlobalData";
4
- import { OriginPrototype } from "./OriginPrototype";
5
4
  import type {
6
5
  DOMUtils_Event,
7
6
  DOMUtils_EventType,
8
7
  DOMUtilsAddEventListenerResult,
9
- DOMUtilsDoubleClickHandler,
10
- DOMUtilsDoubleClickHandlerWithSelector,
11
- DOMUtilsDoubleClickOption,
8
+ DOMUtilsDoubleEventEventListenerOption,
9
+ DOMUtilsDoubleEventHandler,
10
+ DOMUtilsDoubleEventHandlerWithSelector,
11
+ DOMUtilsDoubleEventOption,
12
12
  DOMUtilsElementEventType,
13
13
  DOMUtilsEventListenerOption,
14
14
  DOMUtilsEventListenerOptionsAttribute,
@@ -242,6 +242,9 @@ class ElementEvent extends ElementAnimate {
242
242
  listenerOption = getOption(args, 4, listenerOption);
243
243
  }
244
244
  $elList.forEach(($elItem) => {
245
+ // window和document共用一个对象
246
+ // 这样就能处理子元素选择器无法匹配的问题
247
+ const targetIsWindow = CommonUtils.isWin($elItem);
245
248
  // 遍历事件名设置元素事件
246
249
  eventTypeList.forEach((eventName) => {
247
250
  /**
@@ -275,12 +278,7 @@ class ElementEvent extends ElementAnimate {
275
278
  } else {
276
279
  $target = event.target as HTMLElement;
277
280
  }
278
- let $parent = $elItem;
279
- if (CommonUtils.isWin($parent)) {
280
- // window和document共用一个对象
281
- // 这样就能处理子元素选择器无法匹配的问题
282
- $parent = that.windowApi.document.documentElement;
283
- }
281
+ const $parent = targetIsWindow ? that.windowApi.document.documentElement : $elItem;
284
282
  const findValue = selectorList.find((selectors) => {
285
283
  // 判断目标元素是否匹配选择器
286
284
  if (that.matches($target, selectors)) {
@@ -297,14 +295,7 @@ class ElementEvent extends ElementAnimate {
297
295
  });
298
296
  if (findValue) {
299
297
  // 这里尝试使用defineProperty修改event的target值
300
- try {
301
- OriginPrototype.Object.defineProperty(event, "target", {
302
- get() {
303
- return $target;
304
- },
305
- });
306
- // oxlint-disable-next-line no-empty
307
- } catch {}
298
+ // 不建议使用覆盖target,因为可能会有兼容性问题
308
299
  execCallback = true;
309
300
  call_this = $target;
310
301
  call_event = event;
@@ -612,6 +603,9 @@ class ElementEvent extends ElementAnimate {
612
603
  if (handlers.length === 0) {
613
604
  // 如果没有任意的handler,那么删除该属性
614
605
  CommonUtils.delete(elementEvents, eventType);
606
+ if (Object.keys(elementEvents).length === 0) {
607
+ CommonUtils.delete($elItem, GlobalData.domEventSymbol);
608
+ }
615
609
  }
616
610
  });
617
611
  Reflect.set($elItem, GlobalData.domEventSymbol, elementEvents);
@@ -657,13 +651,13 @@ class ElementEvent extends ElementAnimate {
657
651
  }
658
652
  $elList.forEach(($elItem) => {
659
653
  const symbolList = [...new Set([...Object.getOwnPropertySymbols($elItem), GlobalData.domEventSymbol])];
660
- symbolList.forEach((symbolItem) => {
661
- if (!symbolItem.toString().startsWith("Symbol(events_")) {
654
+ symbolList.forEach((__symbol__) => {
655
+ if (!__symbol__.toString().startsWith("Symbol(events_")) {
662
656
  return;
663
657
  }
664
658
  const elementEvents: {
665
659
  [key: string]: DOMUtilsEventListenerOptionsAttribute[];
666
- } = Reflect.get($elItem, symbolItem) || {};
660
+ } = Reflect.get($elItem, __symbol__) || {};
667
661
  const iterEventNameList = eventTypeList.length ? eventTypeList : Object.keys(elementEvents);
668
662
  iterEventNameList.forEach((eventName) => {
669
663
  const handlers: DOMUtilsEventListenerOptionsAttribute[] = elementEvents[eventName];
@@ -675,8 +669,11 @@ class ElementEvent extends ElementAnimate {
675
669
  capture: handler.option.capture,
676
670
  });
677
671
  }
678
- const events = Reflect.get($elItem, symbolItem);
672
+ const events = Reflect.get($elItem, __symbol__);
679
673
  CommonUtils.delete(events, eventName);
674
+ if (Object.keys(events).length === 0) {
675
+ CommonUtils.delete($elItem, __symbol__);
676
+ }
680
677
  });
681
678
  });
682
679
  });
@@ -1448,44 +1445,44 @@ class ElementEvent extends ElementAnimate {
1448
1445
  };
1449
1446
  }
1450
1447
  /**
1451
- * 双击监听,适配移动端
1448
+ * 监听事件单/双次触发
1452
1449
  * @param $el 监听的元素
1453
1450
  * @param handler 处理的回调函数
1454
1451
  * @param options 监听器的配置
1455
1452
  */
1456
- onDoubleClick(
1453
+ onOneOrDouble(
1457
1454
  $el: DOMUtilsElementEventType,
1458
- handler: (event: MouseEvent | PointerEvent | TouchEvent, option: DOMUtilsDoubleClickOption) => void | Promise<void>,
1459
- options?: DOMUtilsEventListenerOption | boolean
1455
+ handler: (event: Event, option: DOMUtilsDoubleEventOption) => void | Promise<void>,
1456
+ options?: DOMUtilsDoubleEventEventListenerOption | boolean
1460
1457
  ): {
1461
1458
  off(): void;
1462
1459
  };
1463
1460
  /**
1464
- * 双击监听,适配移动端
1461
+ * 监听事件单/双次触发
1465
1462
  * @param $el 监听的元素
1466
1463
  * @param selector 子元素选择器
1467
1464
  * @param handler 处理的回调函数
1468
1465
  * @param options 监听器的配置
1469
1466
  */
1470
- onDoubleClick<T = HTMLElement>(
1467
+ onOneOrDouble<T = HTMLElement>(
1471
1468
  $el: DOMUtilsElementEventType,
1472
1469
  selector: string | string[],
1473
- handler: (
1474
- event: MouseEvent | PointerEvent | TouchEvent,
1470
+ handler: <E extends Event = Event>(
1471
+ event: E,
1475
1472
  $selector: T,
1476
- option: DOMUtilsDoubleClickOption
1473
+ option: DOMUtilsDoubleEventOption
1477
1474
  ) => void | Promise<void>,
1478
- options?: DOMUtilsEventListenerOption | boolean
1475
+ options?: DOMUtilsDoubleEventEventListenerOption | boolean
1479
1476
  ): {
1480
1477
  off(): void;
1481
1478
  };
1482
- onDoubleClick(...args: any[]): {
1479
+ onOneOrDouble(...args: any[]): {
1483
1480
  off(): void;
1484
1481
  } {
1485
1482
  const $el: DOMUtilsElementEventType = args[0];
1486
1483
  let selector: string | string[] | undefined | null = void 0;
1487
- let handler: DOMUtilsDoubleClickHandler | DOMUtilsDoubleClickHandlerWithSelector;
1488
- let options: DOMUtilsEventListenerOption | boolean | undefined;
1484
+ let handler: DOMUtilsDoubleEventHandler | DOMUtilsDoubleEventHandlerWithSelector;
1485
+ let options: DOMUtilsDoubleEventEventListenerOption | boolean | undefined;
1489
1486
  if (args.length === 2) {
1490
1487
  if (typeof args[1] === "function") {
1491
1488
  handler = args[1];
@@ -1508,37 +1505,41 @@ class ElementEvent extends ElementAnimate {
1508
1505
  throw new Error("args length error");
1509
1506
  }
1510
1507
 
1511
- let clickMap = new WeakMap<Element, PointerEvent>();
1512
- let isDoubleClick = false;
1508
+ let eventNodeMap = new WeakMap<Element, Event>();
1509
+ let isDouble = false;
1513
1510
  let timer: number | undefined = void 0;
1511
+ let eventType: DOMUtils_EventType | DOMUtils_EventType[] = "pointerup";
1514
1512
  /** 检测是否是单击的延迟时间 */
1515
- const checkClickTime = 200;
1513
+ let checkClickTime = 200;
1514
+ if (typeof options === "object" && options != null) {
1515
+ if (typeof options.eventType === "string" || Array.isArray(options.eventType)) {
1516
+ eventType = options.eventType;
1517
+ }
1518
+ if (typeof options.checkClickTime === "number") {
1519
+ checkClickTime = options.checkClickTime;
1520
+ }
1521
+ }
1516
1522
 
1517
- const dblclick_handler = (
1518
- evt: MouseEvent | PointerEvent | TouchEvent,
1519
- option: DOMUtilsDoubleClickOption,
1520
- $selector?: HTMLElement
1521
- ) => {
1523
+ const callback = (evt: Event, option: DOMUtilsDoubleEventOption, $selector?: HTMLElement) => {
1522
1524
  if ($selector) {
1523
- return (<DOMUtilsDoubleClickHandlerWithSelector>handler)(evt, $selector, option);
1525
+ return (<DOMUtilsDoubleEventHandlerWithSelector>handler)(evt, $selector, option);
1524
1526
  } else {
1525
- return (<DOMUtilsDoubleClickHandler>handler)(evt, option);
1527
+ return (<DOMUtilsDoubleEventHandler>handler)(evt, option);
1526
1528
  }
1527
1529
  };
1528
1530
 
1529
1531
  const pointerUpListener = this.on(
1530
1532
  $el,
1531
- "pointerup",
1533
+ eventType,
1532
1534
  selector,
1533
1535
  (evt, $selector) => {
1534
- // this.preventEvent(evt);
1535
1536
  clearTimeout(timer);
1536
1537
  timer = void 0;
1537
- if (isDoubleClick && clickMap.has($selector as Element)) {
1538
- isDoubleClick = false;
1539
- clickMap.delete($selector);
1540
- /* 判定为双击 */
1541
- dblclick_handler(
1538
+ if (isDouble && eventNodeMap.has($selector as Element)) {
1539
+ isDouble = false;
1540
+ eventNodeMap.delete($selector);
1541
+ // 判定为双次
1542
+ callback(
1542
1543
  evt,
1543
1544
  {
1544
1545
  isDoubleClick: true,
@@ -1547,9 +1548,9 @@ class ElementEvent extends ElementAnimate {
1547
1548
  );
1548
1549
  } else {
1549
1550
  timer = setTimeout(() => {
1550
- isDoubleClick = false;
1551
- // 判断为单击
1552
- dblclick_handler(
1551
+ isDouble = false;
1552
+ // 判断为单次
1553
+ callback(
1553
1554
  evt,
1554
1555
  {
1555
1556
  isDoubleClick: false,
@@ -1557,8 +1558,8 @@ class ElementEvent extends ElementAnimate {
1557
1558
  $selector
1558
1559
  );
1559
1560
  }, checkClickTime);
1560
- isDoubleClick = true;
1561
- clickMap.set($selector as Element, evt);
1561
+ isDouble = true;
1562
+ eventNodeMap.set($selector as Element, evt);
1562
1563
  }
1563
1564
  },
1564
1565
  options
@@ -1568,7 +1569,7 @@ class ElementEvent extends ElementAnimate {
1568
1569
  off() {
1569
1570
  pointerUpListener.off();
1570
1571
  // @ts-expect-error
1571
- clickMap = null;
1572
+ eventNodeMap = null;
1572
1573
  },
1573
1574
  };
1574
1575
  }
@@ -415,7 +415,7 @@ export declare interface DOMUtilsAddEventListenerResult {
415
415
  /**
416
416
  * 传递的双击配置信息
417
417
  */
418
- export declare type DOMUtilsDoubleClickOption = {
418
+ export declare type DOMUtilsDoubleEventOption = {
419
419
  /**
420
420
  * 是否是双击
421
421
  *
@@ -425,19 +425,35 @@ export declare type DOMUtilsDoubleClickOption = {
425
425
  isDoubleClick: boolean;
426
426
  };
427
427
 
428
+ /**
429
+ * 传入的配置项
430
+ */
431
+ export declare type DOMUtilsDoubleEventEventListenerOption = DOMUtilsEventListenerOption & {
432
+ /**
433
+ * 检测单击的延迟事件
434
+ * @default 200
435
+ */
436
+ checkClickTime?: number;
437
+ /**
438
+ * 监听的事件
439
+ * @default "pointerup"
440
+ */
441
+ eventType?: DOMUtils_EventType;
442
+ };
443
+
428
444
  /**
429
445
  * 双击的处理函数
430
446
  */
431
- export declare type DOMUtilsDoubleClickHandler = (
432
- event: MouseEvent | PointerEvent | TouchEvent,
433
- option: DOMUtilsDoubleClickOption
447
+ export declare type DOMUtilsDoubleEventHandler = (
448
+ event: Event,
449
+ option: DOMUtilsDoubleEventOption
434
450
  ) => void | Promise<void>;
435
451
 
436
452
  /**
437
453
  * 双击的处理函数(传入了selector)
438
454
  */
439
- export declare type DOMUtilsDoubleClickHandlerWithSelector<T = HTMLElement> = (
440
- event: MouseEvent | PointerEvent | TouchEvent,
455
+ export declare type DOMUtilsDoubleEventHandlerWithSelector<T = HTMLElement> = (
456
+ event: Event,
441
457
  $selector: T,
442
- option: DOMUtilsDoubleClickOption
458
+ option: DOMUtilsDoubleEventOption
443
459
  ) => void | Promise<void>;