@whitesev/domutils 1.9.9 → 1.9.11

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.
@@ -1,7 +1,7 @@
1
1
  var DOMUtils = (function () {
2
2
  'use strict';
3
3
 
4
- const version = "1.9.9";
4
+ const version = "1.9.11";
5
5
 
6
6
  class WindowApi {
7
7
  /** 默认的配置 */
@@ -1381,7 +1381,7 @@ var DOMUtils = (function () {
1381
1381
  * @param startIndex
1382
1382
  * @param option
1383
1383
  */
1384
- function getOption(args, startIndex, option) {
1384
+ const getOption = function (args, startIndex, option) {
1385
1385
  const currentParam = args[startIndex];
1386
1386
  if (typeof currentParam === "boolean") {
1387
1387
  option.capture = currentParam;
@@ -1403,7 +1403,7 @@ var DOMUtils = (function () {
1403
1403
  option.isComposedPath = currentParam.isComposedPath;
1404
1404
  }
1405
1405
  return option;
1406
- }
1406
+ };
1407
1407
  const that = this;
1408
1408
  // eslint-disable-next-line prefer-rest-params
1409
1409
  const args = arguments;
@@ -1458,74 +1458,96 @@ var DOMUtils = (function () {
1458
1458
  // 这是存在selector的情况
1459
1459
  listenerOption = getOption(args, 4, listenerOption);
1460
1460
  }
1461
- /**
1462
- * 如果是once,那么删除该监听和元素上的事件和监听
1463
- */
1464
- const checkOptionOnceToRemoveEventListener = () => {
1465
- if (listenerOption.once) {
1466
- that.off(element, eventType, selector, callback, option);
1467
- }
1468
- };
1469
- $elList.forEach((elementItem) => {
1470
- /**
1471
- * 事件回调
1472
- * @param event
1473
- */
1474
- const handlerCallBack = function (event) {
1475
- if (selectorList.length) {
1476
- /* 存在子元素选择器 */
1477
- // 这时候的this和target都是子元素选择器的元素
1478
- let eventTarget = listenerOption.isComposedPath
1479
- ? event.composedPath()[0]
1480
- : event.target;
1481
- let totalParent = elementItem;
1482
- if (CommonUtils.isWin(totalParent)) {
1483
- if (totalParent === that.windowApi.document) {
1484
- totalParent = that.windowApi.document.documentElement;
1485
- }
1461
+ $elList.forEach(($elItem) => {
1462
+ // 遍历事件名设置元素事件
1463
+ eventTypeList.forEach((eventName) => {
1464
+ /**
1465
+ * 如果是option.once,那么删除该监听和元素上的事件和监听
1466
+ */
1467
+ const checkOptionOnceToRemoveEventListener = () => {
1468
+ if (listenerOption.once) {
1469
+ this.off($elItem, eventName, selector, callback, option);
1486
1470
  }
1487
- const findValue = selectorList.find((selectorItem) => {
1488
- // 判断目标元素是否匹配选择器
1489
- if (that.matches(eventTarget, selectorItem)) {
1490
- /* 当前目标可以被selector所匹配到 */
1491
- return true;
1471
+ };
1472
+ /**
1473
+ * 事件回调
1474
+ * @param event
1475
+ */
1476
+ const handlerCallBack = function (event) {
1477
+ let call_this = void 0;
1478
+ let call_event = void 0;
1479
+ let call_$selector = void 0;
1480
+ let execCallback = false;
1481
+ if (selectorList.length) {
1482
+ // 存在子元素选择器
1483
+ // 这时候的this和target都是子元素选择器的元素
1484
+ let $target;
1485
+ if (listenerOption.isComposedPath) {
1486
+ // 可能为空
1487
+ const composedPath = event.composedPath();
1488
+ if (!composedPath.length && event.target) {
1489
+ composedPath.push(event.target);
1490
+ }
1491
+ $target = composedPath[0];
1492
1492
  }
1493
- /* 在上层与主元素之间寻找可以被selector所匹配到的 */
1494
- const $closestMatches = that.closest(eventTarget, selectorItem);
1495
- if ($closestMatches && totalParent?.contains?.($closestMatches)) {
1496
- eventTarget = $closestMatches;
1497
- return true;
1493
+ else {
1494
+ $target = event.target;
1498
1495
  }
1499
- return false;
1500
- });
1501
- if (findValue) {
1502
- // 这里尝试使用defineProperty修改event的target值
1503
- try {
1504
- OriginPrototype.Object.defineProperty(event, "target", {
1505
- get() {
1506
- return eventTarget;
1507
- },
1508
- });
1496
+ let $parent = $elItem;
1497
+ if (CommonUtils.isWin($parent)) {
1498
+ // window和document共用一个对象
1499
+ // 这样就能处理子元素选择器无法匹配的问题
1500
+ $parent = that.windowApi.document.documentElement;
1509
1501
  }
1510
- catch {
1511
- // TODO
1502
+ const findValue = selectorList.find((selectors) => {
1503
+ // 判断目标元素是否匹配选择器
1504
+ if (that.matches($target, selectors)) {
1505
+ // 当前目标可以被selector所匹配到
1506
+ return true;
1507
+ }
1508
+ // 在上层与主元素之间寻找可以被selector所匹配到的
1509
+ const $closestMatches = that.closest($target, selectors);
1510
+ if ($closestMatches && $parent?.contains?.($closestMatches)) {
1511
+ $target = $closestMatches;
1512
+ return true;
1513
+ }
1514
+ return false;
1515
+ });
1516
+ if (findValue) {
1517
+ // 这里尝试使用defineProperty修改event的target值
1518
+ try {
1519
+ OriginPrototype.Object.defineProperty(event, "target", {
1520
+ get() {
1521
+ return $target;
1522
+ },
1523
+ });
1524
+ // oxlint-disable-next-line no-empty
1525
+ }
1526
+ catch { }
1527
+ execCallback = true;
1528
+ call_this = $target;
1529
+ call_event = event;
1530
+ call_$selector = $target;
1512
1531
  }
1513
- listenerCallBack.call(eventTarget, event, eventTarget);
1532
+ }
1533
+ else {
1534
+ execCallback = true;
1535
+ call_this = $elItem;
1536
+ call_event = event;
1537
+ }
1538
+ if (execCallback) {
1539
+ const result = listenerCallBack.call(call_this, call_event, call_$selector);
1514
1540
  checkOptionOnceToRemoveEventListener();
1541
+ if (typeof result === "boolean" && !result) {
1542
+ return false;
1543
+ }
1515
1544
  }
1516
- }
1517
- else {
1518
- // 这时候的this指向监听的元素
1519
- listenerCallBack.call(elementItem, event);
1520
- checkOptionOnceToRemoveEventListener();
1521
- }
1522
- };
1523
- /* 遍历事件名设置元素事件 */
1524
- eventTypeList.forEach((eventName) => {
1525
- elementItem.addEventListener(eventName, handlerCallBack, listenerOption);
1526
- /* 获取对象上的事件 */
1527
- const elementEvents = Reflect.get(elementItem, GlobalData.domEventSymbol) || {};
1528
- /* 初始化对象上的xx事件 */
1545
+ };
1546
+ // add listener
1547
+ $elItem.addEventListener(eventName, handlerCallBack, listenerOption);
1548
+ // 获取对象上的事件
1549
+ const elementEvents = Reflect.get($elItem, GlobalData.domEventSymbol) || {};
1550
+ // 初始化对象上的xx事件
1529
1551
  elementEvents[eventName] = elementEvents[eventName] || [];
1530
1552
  elementEvents[eventName].push({
1531
1553
  selector: selectorList,
@@ -1533,8 +1555,8 @@ var DOMUtils = (function () {
1533
1555
  handlerCallBack: handlerCallBack,
1534
1556
  callback: listenerCallBack,
1535
1557
  });
1536
- /* 覆盖事件 */
1537
- Reflect.set(elementItem, GlobalData.domEventSymbol, elementEvents);
1558
+ // 覆盖事件
1559
+ Reflect.set($elItem, GlobalData.domEventSymbol, elementEvents);
1538
1560
  });
1539
1561
  });
1540
1562
  return {
@@ -1548,7 +1570,7 @@ var DOMUtils = (function () {
1548
1570
  /**
1549
1571
  * 主动触发事件
1550
1572
  * @param extraDetails 赋予触发的Event的额外属性,如果是Event类型,那么将自动代替默认new的Event对象
1551
- * @param useDispatchToTriggerEvent 是否使用dispatchEvent来触发事件,默认true,如果为false,则直接调用callback,但是这种会让使用了$selector的没有值
1573
+ * @param useDispatchToTriggerEvent 是否使用dispatchEvent来触发事件,默认true,如果为false,则直接调用callback,但是这种会让使用了`$selector`的没有值
1552
1574
  */
1553
1575
  emit: (extraDetails, useDispatchToTriggerEvent) => {
1554
1576
  that.emit($elList, eventTypeList, extraDetails, useDispatchToTriggerEvent);
@@ -1562,7 +1584,7 @@ var DOMUtils = (function () {
1562
1584
  * @param startIndex
1563
1585
  * @param option
1564
1586
  */
1565
- function getOption(args1, startIndex, option) {
1587
+ const getOption = function (args1, startIndex, option) {
1566
1588
  const currentParam = args1[startIndex];
1567
1589
  if (typeof currentParam === "boolean") {
1568
1590
  option.capture = currentParam;
@@ -1571,7 +1593,7 @@ var DOMUtils = (function () {
1571
1593
  option.capture = currentParam.capture;
1572
1594
  }
1573
1595
  return option;
1574
- }
1596
+ };
1575
1597
  const that = this;
1576
1598
  // eslint-disable-next-line prefer-rest-params
1577
1599
  const args = arguments;
@@ -1629,40 +1651,43 @@ var DOMUtils = (function () {
1629
1651
  filter = option;
1630
1652
  }
1631
1653
  $elList.forEach(($elItem) => {
1632
- /* 获取对象上的事件 */
1654
+ // 获取对象上的事件
1633
1655
  const elementEvents = Reflect.get($elItem, GlobalData.domEventSymbol) || {};
1634
1656
  eventTypeList.forEach((eventName) => {
1635
1657
  const handlers = elementEvents[eventName] || [];
1636
- const filterHandler = typeof filter === "function" ? handlers.filter(filter) : handlers;
1637
- for (let index = 0; index < filterHandler.length; index++) {
1638
- const handler = filterHandler[index];
1658
+ // 过滤出需要删除的事件
1659
+ const handlersFiltered = typeof filter === "function" ? handlers.filter(filter) : handlers;
1660
+ for (let index = 0; index < handlersFiltered.length; index++) {
1661
+ const handler = handlersFiltered[index];
1662
+ // 过滤出的事件再根据下面的条件进行判断处理移除
1663
+ // 1. callback内存地址必须相同
1664
+ // 2. selector必须相同
1665
+ // 3. option.capture必须相同
1639
1666
  let flag = true;
1640
1667
  if (flag && listenerCallBack && handler.callback !== listenerCallBack) {
1641
- // callback不同
1642
1668
  flag = false;
1643
1669
  }
1644
1670
  if (flag && selectorList.length && Array.isArray(handler.selector)) {
1645
1671
  if (JSON.stringify(handler.selector) !== JSON.stringify(selectorList)) {
1646
- // 子元素选择器不同
1647
1672
  flag = false;
1648
1673
  }
1649
1674
  }
1650
1675
  if (flag &&
1651
1676
  typeof handler.option.capture === "boolean" &&
1652
1677
  listenerOption.capture !== handler.option.capture) {
1653
- // 事件的配置项不同
1654
1678
  flag = false;
1655
1679
  }
1656
1680
  if (flag) {
1657
1681
  $elItem.removeEventListener(eventName, handler.handlerCallBack, handler.option);
1658
- const findIndex = handlers.findIndex((item) => item === handler);
1659
- if (findIndex !== -1) {
1660
- handlers.splice(findIndex, 1);
1682
+ for (let i = handlers.length - 1; i >= 0; i--) {
1683
+ if (handlers[i] === handler) {
1684
+ handlers.splice(i, 1);
1685
+ }
1661
1686
  }
1662
1687
  }
1663
1688
  }
1664
1689
  if (handlers.length === 0) {
1665
- /* 如果没有任意的handler,那么删除该属性 */
1690
+ // 如果没有任意的handler,那么删除该属性
1666
1691
  CommonUtils.delete(elementEvents, eventType);
1667
1692
  }
1668
1693
  });
@@ -2423,11 +2448,11 @@ var DOMUtils = (function () {
2423
2448
  * 阻止事件的默认行为发生,并阻止事件传播
2424
2449
  */
2425
2450
  const stopEvent = (event, onlyStopPropagation) => {
2451
+ // 停止事件的传播,阻止它继续向更上层的元素冒泡,事件将不会再传播给其他的元素
2452
+ event?.stopPropagation();
2453
+ // 阻止事件传播,并且还能阻止元素上的其他事件处理程序被触发
2454
+ event?.stopImmediatePropagation();
2426
2455
  if (typeof onlyStopPropagation === "boolean" && onlyStopPropagation) {
2427
- // 停止事件的传播,阻止它继续向更上层的元素冒泡,事件将不会再传播给其他的元素
2428
- event?.stopPropagation();
2429
- // 阻止事件传播,并且还能阻止元素上的其他事件处理程序被触发
2430
- event?.stopImmediatePropagation();
2431
2456
  return;
2432
2457
  }
2433
2458
  // 阻止事件的默认行为发生。例如,当点击一个链接时,浏览器会默认打开链接的URL,或者在输入框内输入文字