@whitesev/domutils 1.9.10 → 1.9.12

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.10",
4
+ "version": "1.9.12",
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.30001781",
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.0",
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.57.2"
55
55
  },
56
56
  "scripts": {
57
57
  "lint": "oxlint .",
@@ -49,7 +49,7 @@ class ElementEvent extends ElementAnimate {
49
49
  * console.log("事件触发",event)
50
50
  * })
51
51
  */
52
- on<T extends DOMUtils_EventType>(
52
+ on<T extends DOMUtils_EventType = DOMUtils_EventType>(
53
53
  element: DOMUtilsElementEventType,
54
54
  eventType: T | T[],
55
55
  handler: <E extends HTMLElement = HTMLElement>(this: E, event: DOMUtils_Event[T]) => void,
@@ -73,7 +73,7 @@ class ElementEvent extends ElementAnimate {
73
73
  * console.log("事件触发",event)
74
74
  * })
75
75
  */
76
- on<T extends Event>(
76
+ on<T extends Event = Event>(
77
77
  element: DOMUtilsElementEventType,
78
78
  eventType: string | string[],
79
79
  handler: <E extends HTMLElement = HTMLElement>(this: E, event: T) => void,
@@ -103,7 +103,7 @@ class ElementEvent extends ElementAnimate {
103
103
  * console.log("事件触发", event, $selector)
104
104
  * })
105
105
  */
106
- on<T extends DOMUtils_EventType>(
106
+ on<T extends DOMUtils_EventType = DOMUtils_EventType>(
107
107
  element: DOMUtilsElementEventType,
108
108
  eventType: T | T[],
109
109
  selector: string | string[] | undefined | null,
@@ -134,14 +134,14 @@ class ElementEvent extends ElementAnimate {
134
134
  * console.log("事件触发", event, $selector)
135
135
  * })
136
136
  */
137
- on<T extends Event>(
137
+ on<T extends Event = Event>(
138
138
  element: DOMUtilsElementEventType,
139
139
  eventType: string | string[],
140
140
  selector: string | string[] | undefined | null,
141
141
  handler: <E extends HTMLElement = HTMLElement>(this: E, event: T, $selector: E) => void,
142
142
  option?: DOMUtilsEventListenerOption | boolean
143
143
  ): DOMUtilsAddEventListenerResult;
144
- on<T extends Event>(
144
+ on<T extends Event = Event>(
145
145
  element: HTMLElement | string | NodeList | HTMLElement[] | Window | Document | Element | null | typeof globalThis,
146
146
  eventType: DOMUtils_EventType | DOMUtils_EventType[] | string | string[],
147
147
  selector:
@@ -241,89 +241,94 @@ class ElementEvent extends ElementAnimate {
241
241
  // 这是存在selector的情况
242
242
  listenerOption = getOption(args, 4, listenerOption);
243
243
  }
244
- /**
245
- * 如果是once,那么删除该监听和元素上的事件和监听
246
- */
247
- const checkOptionOnceToRemoveEventListener = ($el: DOMUtilsElementEventType) => {
248
- if (listenerOption.once) {
249
- this.off($el, eventTypeList, selector as any, callback as any, option);
250
- }
251
- };
252
244
  $elList.forEach(($elItem) => {
253
- /**
254
- * 事件回调
255
- * @param event
256
- */
257
- const handlerCallBack = function (event: Event) {
258
- let call_this: Element | undefined = void 0;
259
- let call_event: Event | undefined = void 0;
260
- let call_$selector: HTMLElement | undefined = void 0;
261
- let execCallback = false;
262
- if (selectorList.length) {
263
- // 存在子元素选择器
264
- // 这时候的this和target都是子元素选择器的元素
265
- let $target: HTMLElement;
266
- if (listenerOption.isComposedPath) {
267
- // 可能为空
268
- const composedPath = event.composedPath();
269
- if (!composedPath.length && event.target) {
270
- composedPath.push(event.target);
271
- }
272
- $target = composedPath[0] as HTMLElement;
273
- } else {
274
- $target = event.target as HTMLElement;
275
- }
276
- let $parent = $elItem;
277
- if (CommonUtils.isWin($parent)) {
278
- // window和document共用一个对象
279
- // 这样就能处理子元素选择器无法匹配的问题
280
- $parent = that.windowApi.document.documentElement;
245
+ // 遍历事件名设置元素事件
246
+ eventTypeList.forEach((eventName) => {
247
+ /**
248
+ * 如果是option.once,那么删除该监听和元素上的事件和监听
249
+ */
250
+ const checkOptionOnceToRemoveEventListener = () => {
251
+ if (listenerOption.once) {
252
+ this.off($elItem, eventName, selector as any, callback as any, option);
281
253
  }
282
- const findValue = selectorList.find((selectors) => {
283
- // 判断目标元素是否匹配选择器
284
- if (that.matches($target, selectors)) {
285
- // 当前目标可以被selector所匹配到
286
- return true;
254
+ };
255
+ /**
256
+ * 事件回调
257
+ * @param event
258
+ */
259
+ const handlerCallBack = function (event: Event) {
260
+ let call_this: Element | undefined = void 0;
261
+ let call_event: Event | undefined = void 0;
262
+ let call_$selector: HTMLElement | undefined = void 0;
263
+ let execCallback = false;
264
+ if (selectorList.length) {
265
+ // 存在子元素选择器
266
+ // 这时候的this和target都是子元素选择器的元素
267
+ let $target: HTMLElement;
268
+ if (listenerOption.isComposedPath) {
269
+ // 可能为空
270
+ const composedPath = event.composedPath();
271
+ if (!composedPath.length && event.target) {
272
+ composedPath.push(event.target);
273
+ }
274
+ $target = composedPath[0] as HTMLElement;
275
+ } else {
276
+ $target = event.target as HTMLElement;
287
277
  }
288
- // 在上层与主元素之间寻找可以被selector所匹配到的
289
- const $closestMatches = that.closest<HTMLElement>($target, selectors);
290
- if ($closestMatches && (<HTMLElement>$parent)?.contains?.($closestMatches)) {
291
- $target = $closestMatches;
292
- return true;
278
+ let $parent = $elItem;
279
+ if (CommonUtils.isWin($parent)) {
280
+ // window和document共用一个对象
281
+ // 这样就能处理子元素选择器无法匹配的问题
282
+ $parent = that.windowApi.document.documentElement;
293
283
  }
294
- return false;
295
- });
296
- if (findValue) {
297
- // 这里尝试使用defineProperty修改event的target值
298
- try {
299
- OriginPrototype.Object.defineProperty(event, "target", {
300
- get() {
301
- return $target;
302
- },
303
- });
304
- // oxlint-disable-next-line no-empty
305
- } catch {}
284
+ const findValue = selectorList.find((selectors) => {
285
+ // 判断目标元素是否匹配选择器
286
+ if (that.matches($target, selectors)) {
287
+ // 当前目标可以被selector所匹配到
288
+ return true;
289
+ }
290
+ // 在上层与主元素之间寻找可以被selector所匹配到的
291
+ const $closestMatches = that.closest<HTMLElement>($target, selectors);
292
+ if ($closestMatches && (<HTMLElement>$parent)?.contains?.($closestMatches)) {
293
+ $target = $closestMatches;
294
+ return true;
295
+ }
296
+ return false;
297
+ });
298
+ if (findValue) {
299
+ // 这里尝试使用defineProperty修改event的target值
300
+ const originTarget = event.target;
301
+ try {
302
+ OriginPrototype.Object.defineProperty(event, "target", {
303
+ get() {
304
+ return $target;
305
+ },
306
+ });
307
+ OriginPrototype.Object.defineProperty(event, "originTarget", {
308
+ get() {
309
+ return originTarget;
310
+ },
311
+ });
312
+ // oxlint-disable-next-line no-empty
313
+ } catch {}
314
+ execCallback = true;
315
+ call_this = $target;
316
+ call_event = event;
317
+ call_$selector = $target;
318
+ }
319
+ } else {
306
320
  execCallback = true;
307
- call_this = $target;
321
+ call_this = $elItem as Element;
308
322
  call_event = event;
309
- call_$selector = $target;
310
323
  }
311
- } else {
312
- execCallback = true;
313
- call_this = $elItem as Element;
314
- call_event = event;
315
- }
316
- if (execCallback) {
317
- const result = listenerCallBack.call(call_this!, call_event!, call_$selector!);
318
- checkOptionOnceToRemoveEventListener($elItem);
319
- if (typeof result === "boolean" && !result) {
320
- return false;
324
+ if (execCallback) {
325
+ const result = listenerCallBack.call(call_this!, call_event!, call_$selector!);
326
+ checkOptionOnceToRemoveEventListener();
327
+ if (typeof result === "boolean" && !result) {
328
+ return false;
329
+ }
321
330
  }
322
- }
323
- };
324
-
325
- // 遍历事件名设置元素事件
326
- eventTypeList.forEach((eventName) => {
331
+ };
327
332
  // add listener
328
333
  $elItem.addEventListener(eventName, handlerCallBack, listenerOption);
329
334
  // 获取对象上的事件
@@ -380,7 +385,7 @@ class ElementEvent extends ElementAnimate {
380
385
  * DOMUtils.off(document.querySelector("a.xx"),"click")
381
386
  * DOMUtils.off("a.xx","click")
382
387
  */
383
- off<T extends DOMUtils_EventType>(
388
+ off<T extends DOMUtils_EventType = DOMUtils_EventType>(
384
389
  element: DOMUtilsElementEventType,
385
390
  eventType: T | T[],
386
391
  callback?: <E extends HTMLElement = HTMLElement>(this: E, event: DOMUtils_Event[T]) => void,
@@ -404,7 +409,7 @@ class ElementEvent extends ElementAnimate {
404
409
  * DOMUtils.off(document.querySelector("a.xx"),"click")
405
410
  * DOMUtils.off("a.xx","click")
406
411
  */
407
- off<T extends Event>(
412
+ off<T extends Event = Event>(
408
413
  element: DOMUtilsElementEventType,
409
414
  eventType: string | string[],
410
415
  callback?: <E extends HTMLElement = HTMLElement>(this: E, event: T) => void,
@@ -429,7 +434,7 @@ class ElementEvent extends ElementAnimate {
429
434
  * DOMUtils.off(document.querySelector("a.xx"),"click tap hover")
430
435
  * DOMUtils.off("a.xx",["click","tap","hover"])
431
436
  */
432
- off<T extends DOMUtils_EventType>(
437
+ off<T extends DOMUtils_EventType = DOMUtils_EventType>(
433
438
  element: DOMUtilsElementEventType,
434
439
  eventType: T | T[],
435
440
  selector?: string | string[] | undefined | null,
@@ -455,7 +460,7 @@ class ElementEvent extends ElementAnimate {
455
460
  * DOMUtils.off(document.querySelector("a.xx"),"click tap hover")
456
461
  * DOMUtils.off("a.xx",["click","tap","hover"])
457
462
  */
458
- off<T extends Event>(
463
+ off<T extends Event = Event>(
459
464
  element: DOMUtilsElementEventType,
460
465
  eventType: string | string[],
461
466
  selector?: string | string[] | undefined | null,
@@ -467,7 +472,7 @@ class ElementEvent extends ElementAnimate {
467
472
  array: DOMUtilsEventListenerOptionsAttribute[]
468
473
  ) => boolean
469
474
  ): void;
470
- off<T extends Event>(
475
+ off<T extends Event = Event>(
471
476
  element: HTMLElement | string | NodeList | HTMLElement[] | Window | Document | Element | null | typeof globalThis,
472
477
  eventType: DOMUtils_EventType | DOMUtils_EventType[] | string | string[],
473
478
  selector:
@@ -541,7 +546,11 @@ class ElementEvent extends ElementAnimate {
541
546
  /**
542
547
  * 事件的回调函数
543
548
  */
544
- let listenerCallBack: (this: HTMLElement, event: T, $selector: HTMLElement) => void = callback as any;
549
+ let listenerCallBack: (this: HTMLElement, event: T, $selector: HTMLElement) => void = callback as (
550
+ this: HTMLElement,
551
+ event: Event,
552
+ $selector?: HTMLElement
553
+ ) => void | boolean;
545
554
 
546
555
  /**
547
556
  * 事件的配置
@@ -573,17 +582,20 @@ class ElementEvent extends ElementAnimate {
573
582
  } = Reflect.get($elItem, GlobalData.domEventSymbol) || {};
574
583
  eventTypeList.forEach((eventName) => {
575
584
  const handlers = elementEvents[eventName] || [];
576
- const filterHandler = typeof filter === "function" ? handlers.filter(filter) : handlers;
577
- for (let index = 0; index < filterHandler.length; index++) {
578
- const handler = filterHandler[index];
585
+ // 过滤出需要删除的事件
586
+ const handlersFiltered = typeof filter === "function" ? handlers.filter(filter) : handlers;
587
+ for (let index = 0; index < handlersFiltered.length; index++) {
588
+ const handler = handlersFiltered[index];
589
+ // 过滤出的事件再根据下面的条件进行判断处理移除
590
+ // 1. callback内存地址必须相同
591
+ // 2. selector必须相同
592
+ // 3. option.capture必须相同
579
593
  let flag = true;
580
594
  if (flag && listenerCallBack && handler.callback !== listenerCallBack) {
581
- // callback不同
582
595
  flag = false;
583
596
  }
584
597
  if (flag && selectorList.length && Array.isArray(handler.selector)) {
585
598
  if (JSON.stringify(handler.selector) !== JSON.stringify(selectorList)) {
586
- // 子元素选择器不同
587
599
  flag = false;
588
600
  }
589
601
  }
@@ -592,14 +604,14 @@ class ElementEvent extends ElementAnimate {
592
604
  typeof handler.option.capture === "boolean" &&
593
605
  listenerOption.capture !== handler.option.capture
594
606
  ) {
595
- // 事件的配置项不同
596
607
  flag = false;
597
608
  }
598
609
  if (flag) {
599
610
  $elItem.removeEventListener(eventName, handler.handlerCallBack, handler.option);
600
- const findIndex = handlers.findIndex((item) => item === handler);
601
- if (findIndex !== -1) {
602
- handlers.splice(findIndex, 1);
611
+ for (let i = handlers.length - 1; i >= 0; i--) {
612
+ if (handlers[i] === handler) {
613
+ handlers.splice(i, 1);
614
+ }
603
615
  }
604
616
  }
605
617
  }