@whitesev/domutils 1.9.9 → 1.9.10

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.
@@ -162,7 +162,7 @@ class ElementEvent extends ElementAnimate {
162
162
  * @param startIndex
163
163
  * @param option
164
164
  */
165
- function getOption(args: IArguments, startIndex: number, option: DOMUtilsEventListenerOption) {
165
+ const getOption = function (args: IArguments, startIndex: number, option: DOMUtilsEventListenerOption) {
166
166
  const currentParam = args[startIndex];
167
167
  if (typeof currentParam === "boolean") {
168
168
  option.capture = currentParam;
@@ -185,7 +185,7 @@ class ElementEvent extends ElementAnimate {
185
185
  option.isComposedPath = currentParam.isComposedPath;
186
186
  }
187
187
  return option;
188
- }
188
+ };
189
189
 
190
190
  const that = this;
191
191
  // eslint-disable-next-line prefer-rest-params
@@ -220,7 +220,11 @@ class ElementEvent extends ElementAnimate {
220
220
  selectorList.push(selector);
221
221
  }
222
222
  // 事件回调
223
- let listenerCallBack: (this: HTMLElement, event: Event, $selector?: HTMLElement) => void = callback as any;
223
+ let listenerCallBack: (this: Element, event: Event, $selector?: HTMLElement) => void | boolean = callback as (
224
+ this: Element,
225
+ event: Event,
226
+ $selector?: HTMLElement
227
+ ) => void | boolean;
224
228
  // 事件配置
225
229
  let listenerOption: DOMUtilsEventListenerOption = {
226
230
  capture: false,
@@ -240,39 +244,51 @@ class ElementEvent extends ElementAnimate {
240
244
  /**
241
245
  * 如果是once,那么删除该监听和元素上的事件和监听
242
246
  */
243
- const checkOptionOnceToRemoveEventListener = () => {
247
+ const checkOptionOnceToRemoveEventListener = ($el: DOMUtilsElementEventType) => {
244
248
  if (listenerOption.once) {
245
- that.off(element, eventType as any, selector as any, callback as any, option);
249
+ this.off($el, eventTypeList, selector as any, callback as any, option);
246
250
  }
247
251
  };
248
- $elList.forEach((elementItem) => {
252
+ $elList.forEach(($elItem) => {
249
253
  /**
250
254
  * 事件回调
251
255
  * @param event
252
256
  */
253
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;
254
262
  if (selectorList.length) {
255
- /* 存在子元素选择器 */
263
+ // 存在子元素选择器
256
264
  // 这时候的this和target都是子元素选择器的元素
257
- let eventTarget = listenerOption.isComposedPath
258
- ? (event.composedPath()[0] as HTMLElement)
259
- : (event.target as HTMLElement);
260
- let totalParent = elementItem;
261
- if (CommonUtils.isWin(totalParent)) {
262
- if (totalParent === (that.windowApi.document as any as HTMLElement)) {
263
- totalParent = that.windowApi.document.documentElement;
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);
264
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;
265
281
  }
266
- const findValue = selectorList.find((selectorItem) => {
282
+ const findValue = selectorList.find((selectors) => {
267
283
  // 判断目标元素是否匹配选择器
268
- if (that.matches(eventTarget, selectorItem)) {
269
- /* 当前目标可以被selector所匹配到 */
284
+ if (that.matches($target, selectors)) {
285
+ // 当前目标可以被selector所匹配到
270
286
  return true;
271
287
  }
272
- /* 在上层与主元素之间寻找可以被selector所匹配到的 */
273
- const $closestMatches = that.closest<HTMLElement>(eventTarget, selectorItem);
274
- if ($closestMatches && (<HTMLElement>totalParent)?.contains?.($closestMatches)) {
275
- eventTarget = $closestMatches;
288
+ // 在上层与主元素之间寻找可以被selector所匹配到的
289
+ const $closestMatches = that.closest<HTMLElement>($target, selectors);
290
+ if ($closestMatches && (<HTMLElement>$parent)?.contains?.($closestMatches)) {
291
+ $target = $closestMatches;
276
292
  return true;
277
293
  }
278
294
  return false;
@@ -282,30 +298,39 @@ class ElementEvent extends ElementAnimate {
282
298
  try {
283
299
  OriginPrototype.Object.defineProperty(event, "target", {
284
300
  get() {
285
- return eventTarget;
301
+ return $target;
286
302
  },
287
303
  });
288
- } catch {
289
- // TODO
290
- }
291
- listenerCallBack.call(eventTarget, event as any, eventTarget);
292
- checkOptionOnceToRemoveEventListener();
304
+ // oxlint-disable-next-line no-empty
305
+ } catch {}
306
+ execCallback = true;
307
+ call_this = $target;
308
+ call_event = event;
309
+ call_$selector = $target;
293
310
  }
294
311
  } else {
295
- // 这时候的this指向监听的元素
296
- listenerCallBack.call(elementItem as HTMLElement, event as any);
297
- checkOptionOnceToRemoveEventListener();
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;
321
+ }
298
322
  }
299
323
  };
300
324
 
301
- /* 遍历事件名设置元素事件 */
325
+ // 遍历事件名设置元素事件
302
326
  eventTypeList.forEach((eventName) => {
303
- elementItem.addEventListener(eventName, handlerCallBack, listenerOption);
304
- /* 获取对象上的事件 */
327
+ // add listener
328
+ $elItem.addEventListener(eventName, handlerCallBack, listenerOption);
329
+ // 获取对象上的事件
305
330
  const elementEvents: {
306
331
  [k: string]: DOMUtilsEventListenerOptionsAttribute[];
307
- } = Reflect.get(elementItem, GlobalData.domEventSymbol) || {};
308
- /* 初始化对象上的xx事件 */
332
+ } = Reflect.get($elItem, GlobalData.domEventSymbol) || {};
333
+ // 初始化对象上的xx事件
309
334
  elementEvents[eventName] = elementEvents[eventName] || [];
310
335
  elementEvents[eventName].push({
311
336
  selector: selectorList,
@@ -313,8 +338,8 @@ class ElementEvent extends ElementAnimate {
313
338
  handlerCallBack: handlerCallBack,
314
339
  callback: listenerCallBack,
315
340
  });
316
- /* 覆盖事件 */
317
- Reflect.set(elementItem, GlobalData.domEventSymbol, elementEvents);
341
+ // 覆盖事件
342
+ Reflect.set($elItem, GlobalData.domEventSymbol, elementEvents);
318
343
  });
319
344
  });
320
345
 
@@ -335,7 +360,7 @@ class ElementEvent extends ElementAnimate {
335
360
  /**
336
361
  * 主动触发事件
337
362
  * @param extraDetails 赋予触发的Event的额外属性,如果是Event类型,那么将自动代替默认new的Event对象
338
- * @param useDispatchToTriggerEvent 是否使用dispatchEvent来触发事件,默认true,如果为false,则直接调用callback,但是这种会让使用了$selector的没有值
363
+ * @param useDispatchToTriggerEvent 是否使用dispatchEvent来触发事件,默认true,如果为false,则直接调用callback,但是这种会让使用了`$selector`的没有值
339
364
  */
340
365
  emit: (extraDetails?: object, useDispatchToTriggerEvent?: boolean) => {
341
366
  that.emit($elList, eventTypeList, extraDetails, useDispatchToTriggerEvent);
@@ -475,7 +500,7 @@ class ElementEvent extends ElementAnimate {
475
500
  * @param startIndex
476
501
  * @param option
477
502
  */
478
- function getOption(args1: IArguments, startIndex: number, option: EventListenerOptions) {
503
+ const getOption = function (args1: IArguments, startIndex: number, option: EventListenerOptions) {
479
504
  const currentParam: EventListenerOptions | boolean = args1[startIndex];
480
505
  if (typeof currentParam === "boolean") {
481
506
  option.capture = currentParam;
@@ -483,7 +508,7 @@ class ElementEvent extends ElementAnimate {
483
508
  option.capture = currentParam.capture;
484
509
  }
485
510
  return option;
486
- }
511
+ };
487
512
  const that = this;
488
513
  // eslint-disable-next-line prefer-rest-params
489
514
  const args = arguments;
@@ -542,7 +567,7 @@ class ElementEvent extends ElementAnimate {
542
567
  ) => boolean;
543
568
  }
544
569
  $elList.forEach(($elItem) => {
545
- /* 获取对象上的事件 */
570
+ // 获取对象上的事件
546
571
  const elementEvents: {
547
572
  [key: string]: DOMUtilsEventListenerOptionsAttribute[];
548
573
  } = Reflect.get($elItem, GlobalData.domEventSymbol) || {};
@@ -579,7 +604,7 @@ class ElementEvent extends ElementAnimate {
579
604
  }
580
605
  }
581
606
  if (handlers.length === 0) {
582
- /* 如果没有任意的handler,那么删除该属性 */
607
+ // 如果没有任意的handler,那么删除该属性
583
608
  CommonUtils.delete(elementEvents, eventType);
584
609
  }
585
610
  });
@@ -1578,7 +1603,7 @@ class ElementEvent extends ElementAnimate {
1578
1603
  * })
1579
1604
  */
1580
1605
  preventEvent(
1581
- $el: HTMLElement,
1606
+ $el: Element | Document | ShadowRoot,
1582
1607
  eventNameList: string | string[],
1583
1608
  option?: {
1584
1609
  /** (可选)是否捕获,默认false */
@@ -1609,7 +1634,7 @@ class ElementEvent extends ElementAnimate {
1609
1634
  * })
1610
1635
  */
1611
1636
  preventEvent(
1612
- $el: HTMLElement,
1637
+ $el: Element | Document | ShadowRoot,
1613
1638
  eventNameList: string | string[],
1614
1639
  selector: string | string[] | null | undefined,
1615
1640
  option?: {
@@ -1627,11 +1652,11 @@ class ElementEvent extends ElementAnimate {
1627
1652
  * 阻止事件的默认行为发生,并阻止事件传播
1628
1653
  */
1629
1654
  const stopEvent = (event: Event, onlyStopPropagation?: boolean) => {
1655
+ // 停止事件的传播,阻止它继续向更上层的元素冒泡,事件将不会再传播给其他的元素
1656
+ event?.stopPropagation();
1657
+ // 阻止事件传播,并且还能阻止元素上的其他事件处理程序被触发
1658
+ event?.stopImmediatePropagation();
1630
1659
  if (typeof onlyStopPropagation === "boolean" && onlyStopPropagation) {
1631
- // 停止事件的传播,阻止它继续向更上层的元素冒泡,事件将不会再传播给其他的元素
1632
- event?.stopPropagation();
1633
- // 阻止事件传播,并且还能阻止元素上的其他事件处理程序被触发
1634
- event?.stopImmediatePropagation();
1635
1660
  return;
1636
1661
  }
1637
1662
  // 阻止事件的默认行为发生。例如,当点击一个链接时,浏览器会默认打开链接的URL,或者在输入框内输入文字
@@ -1643,7 +1668,7 @@ class ElementEvent extends ElementAnimate {
1643
1668
  const onlyStopPropagation: boolean = args[1];
1644
1669
  return stopEvent(args[0], onlyStopPropagation);
1645
1670
  } else {
1646
- const $el: HTMLElement = args[0];
1671
+ const $el: Element | Document | ShadowRoot = args[0];
1647
1672
  let eventNameList: string | string[] = args[1];
1648
1673
  let selector: string | string[] | null | undefined = void 0;
1649
1674
  let capture = false;
@@ -369,6 +369,7 @@ export declare type DOMUtilsEventListenerOption = AddEventListenerOptions & {
369
369
  * 是否使用 event.composedPath() 来代替 event.target
370
370
  *
371
371
  * 一般用于设置了selector参数
372
+ * @default false
372
373
  */
373
374
  isComposedPath?: boolean;
374
375
  };