@whitesev/domutils 1.8.9 → 1.9.1

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.
@@ -3,7 +3,7 @@ System.register('DOMUtils', [], (function (exports) {
3
3
  return {
4
4
  execute: (function () {
5
5
 
6
- const version = "1.8.9";
6
+ const version = "1.9.1";
7
7
 
8
8
  class WindowApi {
9
9
  /** 默认的配置 */
@@ -314,9 +314,10 @@ System.register('DOMUtils', [], (function (exports) {
314
314
  */
315
315
  matches($el, selector) {
316
316
  selector = selector.trim();
317
- if ($el == null) {
317
+ if ($el == null)
318
+ return false;
319
+ if ($el instanceof Document)
318
320
  return false;
319
- }
320
321
  if (selector.match(/[^\s]{1}:empty$/gi)) {
321
322
  // empty 语法
322
323
  selector = selector.replace(/:empty$/gi, "");
@@ -360,6 +361,10 @@ System.register('DOMUtils', [], (function (exports) {
360
361
  }
361
362
  closest($el, selector) {
362
363
  selector = selector.trim();
364
+ if ($el == null)
365
+ return null;
366
+ if ($el instanceof Document)
367
+ return null;
363
368
  if (selector.match(/[^\s]{1}:empty$/gi)) {
364
369
  // empty 语法
365
370
  selector = selector.replace(/:empty$/gi, "");
@@ -1444,17 +1449,17 @@ System.register('DOMUtils', [], (function (exports) {
1444
1449
  /**
1445
1450
  * 如果是once,那么删除该监听和元素上的事件和监听
1446
1451
  */
1447
- function checkOptionOnceToRemoveEventListener() {
1452
+ const checkOptionOnceToRemoveEventListener = () => {
1448
1453
  if (listenerOption.once) {
1449
1454
  that.off(element, eventType, selector, callback, option);
1450
1455
  }
1451
- }
1456
+ };
1452
1457
  $elList.forEach((elementItem) => {
1453
1458
  /**
1454
1459
  * 事件回调
1455
1460
  * @param event
1456
1461
  */
1457
- function domUtilsEventCallBack(event) {
1462
+ const handlerCallBack = function (event) {
1458
1463
  if (selectorList.length) {
1459
1464
  /* 存在子元素选择器 */
1460
1465
  // 这时候的this和target都是子元素选择器的元素
@@ -1502,10 +1507,10 @@ System.register('DOMUtils', [], (function (exports) {
1502
1507
  listenerCallBack.call(elementItem, event);
1503
1508
  checkOptionOnceToRemoveEventListener();
1504
1509
  }
1505
- }
1510
+ };
1506
1511
  /* 遍历事件名设置元素事件 */
1507
1512
  eventTypeList.forEach((eventName) => {
1508
- elementItem.addEventListener(eventName, domUtilsEventCallBack, listenerOption);
1513
+ elementItem.addEventListener(eventName, handlerCallBack, listenerOption);
1509
1514
  /* 获取对象上的事件 */
1510
1515
  const elementEvents = Reflect.get(elementItem, GlobalData.domEventSymbol) || {};
1511
1516
  /* 初始化对象上的xx事件 */
@@ -1513,8 +1518,8 @@ System.register('DOMUtils', [], (function (exports) {
1513
1518
  elementEvents[eventName].push({
1514
1519
  selector: selectorList,
1515
1520
  option: listenerOption,
1516
- callback: domUtilsEventCallBack,
1517
- originCallBack: listenerCallBack,
1521
+ handlerCallBack: handlerCallBack,
1522
+ callback: listenerCallBack,
1518
1523
  });
1519
1524
  /* 覆盖事件 */
1520
1525
  Reflect.set(elementItem, GlobalData.domEventSymbol, elementEvents);
@@ -1530,11 +1535,11 @@ System.register('DOMUtils', [], (function (exports) {
1530
1535
  },
1531
1536
  /**
1532
1537
  * 主动触发事件
1533
- * @param details 赋予触发的Event的额外属性,如果是Event类型,那么将自动代替默认new的Event对象
1534
- * @param useDispatchToEmit 是否使用dispatchEvent来触发事件,默认true,如果为false,则直接调用callback,但是这种会让使用了selectorTarget的没有值
1538
+ * @param extraDetails 赋予触发的Event的额外属性,如果是Event类型,那么将自动代替默认new的Event对象
1539
+ * @param useDispatchToTriggerEvent 是否使用dispatchEvent来触发事件,默认true,如果为false,则直接调用callback,但是这种会让使用了$selector的没有值
1535
1540
  */
1536
- emit: (details, useDispatchToEmit) => {
1537
- that.emit($elList, eventTypeList, details, useDispatchToEmit);
1541
+ emit: (extraDetails, useDispatchToTriggerEvent) => {
1542
+ that.emit($elList, eventTypeList, extraDetails, useDispatchToTriggerEvent);
1538
1543
  },
1539
1544
  };
1540
1545
  }
@@ -1630,7 +1635,7 @@ System.register('DOMUtils', [], (function (exports) {
1630
1635
  for (let index = 0; index < filterHandler.length; index++) {
1631
1636
  const handler = filterHandler[index];
1632
1637
  let flag = true;
1633
- if (flag && listenerCallBack && handler.originCallBack !== listenerCallBack) {
1638
+ if (flag && listenerCallBack && handler.callback !== listenerCallBack) {
1634
1639
  // callback不同
1635
1640
  flag = false;
1636
1641
  }
@@ -1647,7 +1652,7 @@ System.register('DOMUtils', [], (function (exports) {
1647
1652
  flag = false;
1648
1653
  }
1649
1654
  if (flag || isRemoveAll) {
1650
- $elItem.removeEventListener(eventName, handler.callback, handler.option);
1655
+ $elItem.removeEventListener(eventName, handler.handlerCallBack, handler.option);
1651
1656
  const findIndex = handlers.findIndex((item) => item === handler);
1652
1657
  if (findIndex !== -1) {
1653
1658
  handlers.splice(findIndex, 1);
@@ -1703,8 +1708,8 @@ System.register('DOMUtils', [], (function (exports) {
1703
1708
  return;
1704
1709
  }
1705
1710
  for (const handler of handlers) {
1706
- $elItem.removeEventListener(eventName, handler.callback, {
1707
- capture: handler["option"]["capture"],
1711
+ $elItem.removeEventListener(eventName, handler.handlerCallBack, {
1712
+ capture: handler.option.capture,
1708
1713
  });
1709
1714
  }
1710
1715
  const events = Reflect.get($elItem, symbolItem);
@@ -1718,36 +1723,6 @@ System.register('DOMUtils', [], (function (exports) {
1718
1723
  // 异步回调
1719
1724
  let resolve = void 0;
1720
1725
  const that = this;
1721
- /**
1722
- * 检测文档是否加载完毕
1723
- */
1724
- function checkDOMReadyState() {
1725
- try {
1726
- if (that.windowApi.document.readyState === "complete" ||
1727
- (that.windowApi.document.readyState !== "loading" &&
1728
- !that.windowApi.document.documentElement.doScroll)) {
1729
- return true;
1730
- }
1731
- else {
1732
- return false;
1733
- }
1734
- }
1735
- catch {
1736
- return false;
1737
- }
1738
- }
1739
- /**
1740
- * 成功加载完毕后触发的回调函数
1741
- */
1742
- function completed() {
1743
- removeDomReadyListener();
1744
- if (typeof callback === "function") {
1745
- callback();
1746
- }
1747
- if (typeof resolve === "function") {
1748
- resolve();
1749
- }
1750
- }
1751
1726
  /**
1752
1727
  * 监听目标
1753
1728
  */
@@ -1755,59 +1730,97 @@ System.register('DOMUtils', [], (function (exports) {
1755
1730
  {
1756
1731
  target: that.windowApi.document,
1757
1732
  eventType: "DOMContentLoaded",
1758
- callback: completed,
1733
+ callback: () => {
1734
+ ReadyChecker.completed();
1735
+ },
1759
1736
  },
1760
1737
  {
1761
1738
  target: that.windowApi.window,
1762
1739
  eventType: "load",
1763
- callback: completed,
1740
+ callback: () => {
1741
+ ReadyChecker.completed();
1742
+ },
1764
1743
  },
1765
1744
  ];
1766
- /**
1767
- * 添加监听
1768
- */
1769
- function addDomReadyListener() {
1770
- for (const item of listenTargetList) {
1771
- that.on(item.target, item.eventType, item.callback);
1772
- }
1773
- }
1774
- /**
1775
- * 移除监听
1776
- */
1777
- function removeDomReadyListener() {
1778
- for (const item of listenTargetList) {
1779
- that.off(item.target, item.eventType, item.callback);
1780
- }
1781
- }
1782
- /**
1783
- * 执行检查
1784
- */
1785
- function check() {
1786
- if (checkDOMReadyState()) {
1787
- /* 检查document状态 */
1788
- setTimeout(completed, 0);
1789
- }
1790
- else {
1791
- /* 添加监听 */
1792
- addDomReadyListener();
1793
- }
1794
- }
1795
- if (args.length === 0) {
1796
- return new Promise((__resolve__) => {
1797
- resolve = __resolve__;
1798
- check();
1799
- });
1800
- }
1801
- else {
1802
- check();
1803
- }
1745
+ const ReadyChecker = {
1746
+ init() {
1747
+ if (args.length === 0) {
1748
+ return new Promise((__resolve__) => {
1749
+ resolve = __resolve__;
1750
+ ReadyChecker.check();
1751
+ });
1752
+ }
1753
+ else {
1754
+ ReadyChecker.check();
1755
+ }
1756
+ },
1757
+ check() {
1758
+ if (ReadyChecker.isReady()) {
1759
+ /* 检查document状态 */
1760
+ setTimeout(() => {
1761
+ ReadyChecker.completed();
1762
+ }, 0);
1763
+ }
1764
+ else {
1765
+ /* 添加监听 */
1766
+ ReadyChecker.onCompleted();
1767
+ }
1768
+ },
1769
+ /**
1770
+ * 检测文档是否加载完毕
1771
+ */
1772
+ isReady() {
1773
+ try {
1774
+ if (that.windowApi.document.readyState === "complete" ||
1775
+ // @ts-expect-error
1776
+ (that.windowApi.document.readyState !== "loading" && !that.windowApi.document.documentElement.doScroll)) {
1777
+ return true;
1778
+ }
1779
+ else {
1780
+ return false;
1781
+ }
1782
+ }
1783
+ catch {
1784
+ return false;
1785
+ }
1786
+ },
1787
+ /**
1788
+ * 成功加载完毕后触发的回调函数
1789
+ */
1790
+ completed() {
1791
+ ReadyChecker.offCompleted();
1792
+ if (typeof callback === "function") {
1793
+ callback();
1794
+ }
1795
+ if (typeof resolve === "function") {
1796
+ resolve();
1797
+ }
1798
+ },
1799
+ /**
1800
+ * 添加监听
1801
+ */
1802
+ onCompleted() {
1803
+ for (const item of listenTargetList) {
1804
+ that.on(item.target, item.eventType, item.callback);
1805
+ }
1806
+ },
1807
+ /**
1808
+ * 移除监听
1809
+ */
1810
+ offCompleted() {
1811
+ for (const item of listenTargetList) {
1812
+ that.off(item.target, item.eventType, item.callback);
1813
+ }
1814
+ },
1815
+ };
1816
+ return ReadyChecker.init();
1804
1817
  }
1805
1818
  /**
1806
1819
  * 主动触发事件
1807
1820
  * @param element 需要触发的元素|元素数组|window
1808
1821
  * @param eventType 需要触发的事件
1809
- * @param details 赋予触发的Event的额外属性,如果是Event类型,那么将自动代替默认new的Event对象
1810
- * @param useDispatchToEmit 是否使用dispatchEvent来触发事件,默认true,如果为false,则直接调用callback,但是这种会让使用了selectorTarget的没有值
1822
+ * @param extraDetails 赋予触发的Event的额外属性,如果是Event类型,那么将自动代替默认new的Event对象
1823
+ * @param useDispatchToTriggerEvent 是否使用dispatchEvent来触发事件,默认true,如果为false,则直接调用通过.on监听的callback(),但是这种只有一个入参,如果使用$selector则没有值
1811
1824
  * @example
1812
1825
  * // 触发元素a.xx的click事件
1813
1826
  * DOMUtils.emit(document.querySelector("a.xx"),"click")
@@ -1816,7 +1829,7 @@ System.register('DOMUtils', [], (function (exports) {
1816
1829
  * DOMUtils.emit(document.querySelector("a.xx"),"click tap hover")
1817
1830
  * DOMUtils.emit("a.xx",["click","tap","hover"])
1818
1831
  */
1819
- emit(element, eventType, details, useDispatchToEmit = true) {
1832
+ emit(element, eventType, extraDetails, useDispatchToTriggerEvent = true) {
1820
1833
  const that = this;
1821
1834
  if (typeof element === "string") {
1822
1835
  element = that.selectorAll(element);
@@ -1843,25 +1856,25 @@ System.register('DOMUtils', [], (function (exports) {
1843
1856
  const elementEvents = Reflect.get($elItem, GlobalData.domEventSymbol) || {};
1844
1857
  eventTypeList.forEach((eventTypeItem) => {
1845
1858
  let event = null;
1846
- if (details && details instanceof Event) {
1847
- event = details;
1859
+ if (extraDetails && extraDetails instanceof Event) {
1860
+ event = extraDetails;
1848
1861
  }
1849
1862
  else {
1850
1863
  // 构造事件
1851
1864
  event = new Event(eventTypeItem);
1852
- if (details) {
1853
- const detailKeys = Object.keys(details);
1865
+ if (typeof extraDetails === "object" && extraDetails != null) {
1866
+ const detailKeys = Object.keys(extraDetails);
1854
1867
  detailKeys.forEach((keyName) => {
1855
- const value = Reflect.get(details, keyName);
1868
+ const value = Reflect.get(extraDetails, keyName);
1856
1869
  // 在event上添加属性
1857
1870
  Reflect.set(event, keyName, value);
1858
1871
  });
1859
1872
  }
1860
1873
  }
1861
- if (useDispatchToEmit == false && eventTypeItem in elementEvents) {
1874
+ if (useDispatchToTriggerEvent == false && eventTypeItem in elementEvents) {
1862
1875
  // 直接调用监听的事件
1863
1876
  elementEvents[eventTypeItem].forEach((eventsItem) => {
1864
- eventsItem.callback(event);
1877
+ eventsItem.handlerCallBack(event);
1865
1878
  });
1866
1879
  }
1867
1880
  else {
@@ -2347,14 +2360,14 @@ System.register('DOMUtils', [], (function (exports) {
2347
2360
  isDoubleClick: true,
2348
2361
  });
2349
2362
  }, options);
2350
- const touchEndListener = this.on($el, "pointerup", selector, (evt, selectorTarget) => {
2363
+ const touchEndListener = this.on($el, "pointerup", selector, (evt, $selector) => {
2351
2364
  this.preventEvent(evt);
2352
2365
  if (evt.pointerType === "touch") {
2353
2366
  isMobileTouch = true;
2354
2367
  }
2355
2368
  clearTimeout(timer);
2356
2369
  timer = void 0;
2357
- if (isDoubleClick && $click === selectorTarget) {
2370
+ if (isDoubleClick && $click === $selector) {
2358
2371
  isDoubleClick = false;
2359
2372
  $click = null;
2360
2373
  /* 判定为双击 */
@@ -2371,7 +2384,7 @@ System.register('DOMUtils', [], (function (exports) {
2371
2384
  });
2372
2385
  }, checkClickTime);
2373
2386
  isDoubleClick = true;
2374
- $click = selectorTarget;
2387
+ $click = $selector;
2375
2388
  }
2376
2389
  }, options);
2377
2390
  return {
@@ -3575,6 +3588,41 @@ System.register('DOMUtils', [], (function (exports) {
3575
3588
  return parseHTMLByCreateDom();
3576
3589
  }
3577
3590
  }
3591
+ /**
3592
+ * 将字符串转为Element元素数组
3593
+ * @param html
3594
+ * @param useParser 是否使用DOMParser来生成元素,有些时候通过DOMParser生成的元素有点问题
3595
+ * + true 使用DOMPraser来转换字符串
3596
+ * + false (默认)创建一个div,里面放入字符串,然后提取childNodes
3597
+ * @example
3598
+ * // 将字符串转为Element元素数组
3599
+ * DOMUtils.toElements("<a href='xxxx'></a>")
3600
+ * > [<a href="xxxx"></a>]
3601
+ * @example
3602
+ * // 使用DOMParser将字符串转为Element元素数组
3603
+ * DOMUtils.toElements("<a href='xxxx'></a>",true)
3604
+ * > [<a href="xxxx"></a>]
3605
+ */
3606
+ toElements(html, useParser = false) {
3607
+ const that = this;
3608
+ // 去除html前后的空格
3609
+ html = html.trim();
3610
+ function parseHTMLByDOMParser() {
3611
+ const parser = new DOMParser();
3612
+ return Array.from(parser.parseFromString(html, "text/html").body.childNodes);
3613
+ }
3614
+ function parseHTMLByCreateDom() {
3615
+ const $el = that.windowApi.document.createElement("div");
3616
+ that.html($el, html);
3617
+ return Array.from($el.childNodes);
3618
+ }
3619
+ if (useParser) {
3620
+ return parseHTMLByDOMParser();
3621
+ }
3622
+ else {
3623
+ return parseHTMLByCreateDom();
3624
+ }
3625
+ }
3578
3626
  /**
3579
3627
  * 序列化表单元素
3580
3628
  * @param $form 表单元素
@@ -3583,26 +3631,29 @@ System.register('DOMUtils', [], (function (exports) {
3583
3631
  * > xxx=xxx&aaa=
3584
3632
  */
3585
3633
  serialize($form) {
3634
+ if (!($form instanceof HTMLFormElement)) {
3635
+ throw new TypeError("DOMUtils.serialize 参数必须是HTMLFormElement");
3636
+ }
3586
3637
  const elements = $form.elements;
3587
3638
  const serializedArray = [];
3588
- for (let i = 0; i < elements.length; i++) {
3589
- const element = elements[i];
3590
- if (element.name &&
3591
- !element.disabled &&
3592
- (element.checked ||
3593
- ["text", "hidden", "password", "textarea", "select-one", "select-multiple"].includes(element.type))) {
3594
- if (element.type === "select-multiple") {
3595
- for (let j = 0; j < element.options.length; j++) {
3596
- if (element.options[j].selected) {
3639
+ for (let index = 0; index < elements.length; index++) {
3640
+ const $el = elements[index];
3641
+ if ($el.name &&
3642
+ !$el.disabled &&
3643
+ ($el.checked ||
3644
+ ["text", "hidden", "password", "textarea", "select-one", "select-multiple"].includes($el.type))) {
3645
+ if ($el.type === "select-multiple") {
3646
+ for (let j = 0; j < $el.options.length; j++) {
3647
+ if ($el.options[j].selected) {
3597
3648
  serializedArray.push({
3598
- name: element.name,
3599
- value: element.options[j].value,
3649
+ name: $el.name,
3650
+ value: $el.options[j].value,
3600
3651
  });
3601
3652
  }
3602
3653
  }
3603
3654
  }
3604
3655
  else {
3605
- serializedArray.push({ name: element.name, value: element.value });
3656
+ serializedArray.push({ name: $el.name, value: $el.value });
3606
3657
  }
3607
3658
  }
3608
3659
  }