@whitesev/domutils 1.5.6 → 1.5.8

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.
@@ -2,11 +2,6 @@ import { DOMUtilsEvent } from "./DOMUtilsEvent";
2
2
  import type { DOMUtilsCreateElementAttributesMap } from "./types/DOMUtilsEvent";
3
3
  import { ParseHTMLReturnType, type DOMUtilsTargetElementType } from "./types/global";
4
4
  import type { WindowApiOption } from "./types/WindowApi";
5
- /**
6
- * 判断是否是元素列表
7
- * @param $ele
8
- */
9
- export declare const isNodeList: ($ele: any) => $ele is any[] | NodeList;
10
5
  declare class DOMUtils extends DOMUtilsEvent {
11
6
  constructor(option?: WindowApiOption);
12
7
  /** 版本号 */
@@ -60,5 +60,10 @@ declare const DOMUtilsCommonUtils: {
60
60
  * 配合 .setInterval 使用
61
61
  */
62
62
  clearInterval(timeId: number | undefined): void;
63
+ /**
64
+ * 判断是否是元素列表
65
+ * @param $ele
66
+ */
67
+ isNodeList($ele: any): $ele is any[] | NodeList;
63
68
  };
64
69
  export { DOMUtilsCommonUtils };
@@ -382,7 +382,7 @@ export declare class DOMUtilsEvent {
382
382
  * + :contains([text]) 作用: 找到包含指定文本内容的指定元素
383
383
  * + :empty 作用:找到既没有文本内容也没有子元素的指定元素
384
384
  * + :regexp([text]) 作用: 找到符合正则表达式的内容的指定元素
385
- * @param selector
385
+ * @param selector 选择器
386
386
  * @example
387
387
  * DOMUtils.selector("div:contains('测试')")
388
388
  * > div.xxx
@@ -401,7 +401,7 @@ export declare class DOMUtilsEvent {
401
401
  * + :contains([text]) 作用: 找到包含指定文本内容的指定元素
402
402
  * + :empty 作用:找到既没有文本内容也没有子元素的指定元素
403
403
  * + :regexp([text]) 作用: 找到符合正则表达式的内容的指定元素
404
- * @param selector
404
+ * @param selector 选择器
405
405
  * @example
406
406
  * DOMUtils.selectorAll("div:contains('测试')")
407
407
  * > [div.xxx]
@@ -417,4 +417,49 @@ export declare class DOMUtilsEvent {
417
417
  */
418
418
  selectorAll<K extends keyof HTMLElementTagNameMap>(selector: K): HTMLElementTagNameMap[K][];
419
419
  selectorAll<E extends Element = Element>(selector: string): E[];
420
+ /**
421
+ * 匹配元素,可使用以下的额外语法
422
+ *
423
+ * + :contains([text]) 作用: 找到包含指定文本内容的指定元素
424
+ * + :empty 作用:找到既没有文本内容也没有子元素的指定元素
425
+ * + :regexp([text]) 作用: 找到符合正则表达式的内容的指定元素
426
+ * @param $el 元素
427
+ * @param selector 选择器
428
+ * @example
429
+ * DOMUtils.matches("div:contains('测试')")
430
+ * > true
431
+ * @example
432
+ * DOMUtils.matches("div:empty")
433
+ * > true
434
+ * @example
435
+ * DOMUtils.matches("div:regexp('^xxxx$')")
436
+ * > true
437
+ * @example
438
+ * DOMUtils.matches("div:regexp(/^xxx/ig)")
439
+ * > false
440
+ */
441
+ matches($el: HTMLElement | Element | null | undefined, selector: string): boolean;
442
+ /**
443
+ * 根据选择器获取上层元素,可使用以下的额外语法
444
+ *
445
+ * + :contains([text]) 作用: 找到包含指定文本内容的指定元素
446
+ * + :empty 作用:找到既没有文本内容也没有子元素的指定元素
447
+ * + :regexp([text]) 作用: 找到符合正则表达式的内容的指定元素
448
+ * @param $el 元素
449
+ * @param selector 选择器
450
+ * @example
451
+ * DOMUtils.closest("div:contains('测试')")
452
+ * > div.xxx
453
+ * @example
454
+ * DOMUtils.closest("div:empty")
455
+ * > div.xxx
456
+ * @example
457
+ * DOMUtils.closest("div:regexp('^xxxx$')")
458
+ * > div.xxxx
459
+ * @example
460
+ * DOMUtils.closest("div:regexp(/^xxx/ig)")
461
+ * > null
462
+ */
463
+ closest<K extends keyof HTMLElementTagNameMap>($el: HTMLElement | Element, selector: string): HTMLElementTagNameMap[K] | null;
464
+ closest<E extends Element = Element>($el: HTMLElement | Element, selector: string): E | null;
420
465
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@whitesev/domutils",
3
- "version": "1.5.6",
3
+ "version": "1.5.8",
4
4
  "description": "使用js重新对jQuery的部分函数进行了仿写",
5
5
  "main": "dist/index.cjs.js",
6
6
  "module": "dist/index.esm.js",
package/src/DOMUtils.ts CHANGED
@@ -7,20 +7,12 @@ import {
7
7
  } from "./types/global";
8
8
  import type { WindowApiOption } from "./types/WindowApi";
9
9
 
10
- /**
11
- * 判断是否是元素列表
12
- * @param $ele
13
- */
14
- export const isNodeList = ($ele: any): $ele is any[] | NodeList => {
15
- return Array.isArray($ele) || $ele instanceof NodeList;
16
- };
17
-
18
10
  class DOMUtils extends DOMUtilsEvent {
19
11
  constructor(option?: WindowApiOption) {
20
12
  super(option);
21
13
  }
22
14
  /** 版本号 */
23
- version = "2025.5.26";
15
+ version = "2025.5.30";
24
16
  /**
25
17
  * 获取元素的属性值
26
18
  * @param element 目标元素
@@ -55,7 +47,7 @@ class DOMUtils extends DOMUtilsEvent {
55
47
  if (element == null) {
56
48
  return;
57
49
  }
58
- if (isNodeList(element)) {
50
+ if (DOMUtilsCommonUtils.isNodeList(element)) {
59
51
  if (attrValue == null) {
60
52
  // 获取属性
61
53
  return DOMUtilsContext.attr(
@@ -264,7 +256,7 @@ class DOMUtils extends DOMUtilsEvent {
264
256
  if (element == null) {
265
257
  return;
266
258
  }
267
- if (isNodeList(element)) {
259
+ if (DOMUtilsCommonUtils.isNodeList(element)) {
268
260
  if (typeof property === "string") {
269
261
  if (value == null) {
270
262
  // 获取属性
@@ -356,7 +348,7 @@ class DOMUtils extends DOMUtilsEvent {
356
348
  if (element == null) {
357
349
  return;
358
350
  }
359
- if (isNodeList(element)) {
351
+ if (DOMUtilsCommonUtils.isNodeList(element)) {
360
352
  if (text == null) {
361
353
  // 获取
362
354
  return DOMUtilsContext.text(element[0] as HTMLElement);
@@ -417,7 +409,7 @@ class DOMUtils extends DOMUtilsEvent {
417
409
  if (element == null) {
418
410
  return;
419
411
  }
420
- if (isNodeList(element)) {
412
+ if (DOMUtilsCommonUtils.isNodeList(element)) {
421
413
  if (html == null) {
422
414
  // 获取
423
415
  return DOMUtilsContext.html(element[0] as HTMLElement);
@@ -556,7 +548,7 @@ class DOMUtils extends DOMUtilsEvent {
556
548
  if (element == null) {
557
549
  return;
558
550
  }
559
- if (isNodeList(element)) {
551
+ if (DOMUtilsCommonUtils.isNodeList(element)) {
560
552
  if (value == null) {
561
553
  // 获取
562
554
  return DOMUtilsContext.val(element[0] as HTMLInputElement);
@@ -626,7 +618,7 @@ class DOMUtils extends DOMUtilsEvent {
626
618
  if (element == null) {
627
619
  return;
628
620
  }
629
- if (isNodeList(element)) {
621
+ if (DOMUtilsCommonUtils.isNodeList(element)) {
630
622
  if (propValue == null) {
631
623
  // 获取
632
624
  return DOMUtilsContext.prop(element[0] as HTMLElement, propName);
@@ -665,7 +657,7 @@ class DOMUtils extends DOMUtilsEvent {
665
657
  if (element == null) {
666
658
  return;
667
659
  }
668
- if (isNodeList(element)) {
660
+ if (DOMUtilsCommonUtils.isNodeList(element)) {
669
661
  // 设置
670
662
  element.forEach(($ele) => {
671
663
  DOMUtilsContext.removeAttr($ele as HTMLElement, attrName);
@@ -694,7 +686,7 @@ class DOMUtils extends DOMUtilsEvent {
694
686
  if (element == null) {
695
687
  return;
696
688
  }
697
- if (isNodeList(element)) {
689
+ if (DOMUtilsCommonUtils.isNodeList(element)) {
698
690
  // 设置
699
691
  element.forEach(($ele) => {
700
692
  DOMUtilsContext.removeClass($ele as HTMLElement, className);
@@ -730,7 +722,7 @@ class DOMUtils extends DOMUtilsEvent {
730
722
  if (element == null) {
731
723
  return;
732
724
  }
733
- if (isNodeList(element)) {
725
+ if (DOMUtilsCommonUtils.isNodeList(element)) {
734
726
  // 设置
735
727
  element.forEach(($ele) => {
736
728
  DOMUtilsContext.removeProp($ele as HTMLElement, propName);
@@ -759,7 +751,7 @@ class DOMUtils extends DOMUtilsEvent {
759
751
  if (element == null) {
760
752
  return;
761
753
  }
762
- if (isNodeList(element)) {
754
+ if (DOMUtilsCommonUtils.isNodeList(element)) {
763
755
  // 设置
764
756
  element.forEach(($ele) => {
765
757
  DOMUtilsContext.replaceWith($ele as HTMLElement, newElement);
@@ -788,7 +780,7 @@ class DOMUtils extends DOMUtilsEvent {
788
780
  if (element == null) {
789
781
  return;
790
782
  }
791
- if (isNodeList(element)) {
783
+ if (DOMUtilsCommonUtils.isNodeList(element)) {
792
784
  // 设置
793
785
  element.forEach(($ele) => {
794
786
  DOMUtilsContext.addClass($ele as HTMLElement, className);
@@ -821,7 +813,7 @@ class DOMUtils extends DOMUtilsEvent {
821
813
  if (element == null) {
822
814
  return false;
823
815
  }
824
- if (isNodeList(element)) {
816
+ if (DOMUtilsCommonUtils.isNodeList(element)) {
825
817
  let flag = true;
826
818
  for (let index = 0; index < element.length; index++) {
827
819
  const $ele = element[index] as HTMLElement;
@@ -868,7 +860,7 @@ class DOMUtils extends DOMUtilsEvent {
868
860
  return;
869
861
  }
870
862
 
871
- if (isNodeList(element)) {
863
+ if (DOMUtilsCommonUtils.isNodeList(element)) {
872
864
  // 设置
873
865
  element.forEach(($ele) => {
874
866
  DOMUtilsContext.append($ele as HTMLElement, content);
@@ -917,7 +909,7 @@ class DOMUtils extends DOMUtilsEvent {
917
909
  if (element == null) {
918
910
  return;
919
911
  }
920
- if (isNodeList(element)) {
912
+ if (DOMUtilsCommonUtils.isNodeList(element)) {
921
913
  // 设置
922
914
  element.forEach(($ele) => {
923
915
  DOMUtilsContext.prepend($ele as HTMLElement, content);
@@ -955,7 +947,7 @@ class DOMUtils extends DOMUtilsEvent {
955
947
  if (element == null) {
956
948
  return;
957
949
  }
958
- if (isNodeList(element)) {
950
+ if (DOMUtilsCommonUtils.isNodeList(element)) {
959
951
  // 设置
960
952
  element.forEach(($ele) => {
961
953
  DOMUtilsContext.after($ele as HTMLElement, content);
@@ -995,7 +987,7 @@ class DOMUtils extends DOMUtilsEvent {
995
987
  if (element == null) {
996
988
  return;
997
989
  }
998
- if (isNodeList(element)) {
990
+ if (DOMUtilsCommonUtils.isNodeList(element)) {
999
991
  // 设置
1000
992
  element.forEach(($ele) => {
1001
993
  DOMUtilsContext.before($ele as HTMLElement, content);
@@ -1033,7 +1025,7 @@ class DOMUtils extends DOMUtilsEvent {
1033
1025
  if (element == null) {
1034
1026
  return;
1035
1027
  }
1036
- if (isNodeList(element)) {
1028
+ if (DOMUtilsCommonUtils.isNodeList(element)) {
1037
1029
  element.forEach(($ele) => {
1038
1030
  DOMUtilsContext.remove($ele as HTMLElement);
1039
1031
  });
@@ -1057,7 +1049,7 @@ class DOMUtils extends DOMUtilsEvent {
1057
1049
  if (element == null) {
1058
1050
  return;
1059
1051
  }
1060
- if (isNodeList(element)) {
1052
+ if (DOMUtilsCommonUtils.isNodeList(element)) {
1061
1053
  // 设置
1062
1054
  element.forEach(($ele) => {
1063
1055
  DOMUtilsContext.empty($ele as HTMLElement);
@@ -1425,7 +1417,7 @@ class DOMUtils extends DOMUtilsEvent {
1425
1417
  if (element == null) {
1426
1418
  return;
1427
1419
  }
1428
- if (isNodeList(element)) {
1420
+ if (DOMUtilsCommonUtils.isNodeList(element)) {
1429
1421
  // 设置
1430
1422
  element.forEach(($ele) => {
1431
1423
  DOMUtilsContext.animate(
@@ -1496,7 +1488,7 @@ class DOMUtils extends DOMUtilsEvent {
1496
1488
  if (element == null) {
1497
1489
  return;
1498
1490
  }
1499
- if (isNodeList(element)) {
1491
+ if (DOMUtilsCommonUtils.isNodeList(element)) {
1500
1492
  // 设置
1501
1493
  element.forEach(($ele) => {
1502
1494
  DOMUtilsContext.wrap($ele as HTMLElement, wrapperHTML);
@@ -1636,7 +1628,7 @@ class DOMUtils extends DOMUtilsEvent {
1636
1628
  if (element == null) {
1637
1629
  return;
1638
1630
  }
1639
- if (isNodeList(element)) {
1631
+ if (DOMUtilsCommonUtils.isNodeList(element)) {
1640
1632
  let resultArray: HTMLElement[] = [];
1641
1633
  element.forEach(($ele) => {
1642
1634
  resultArray.push(DOMUtilsContext.parent($ele as HTMLElement));
@@ -1860,7 +1852,7 @@ class DOMUtils extends DOMUtilsEvent {
1860
1852
  if (typeof element === "string") {
1861
1853
  element = DOMUtilsContext.selectorAll(element);
1862
1854
  }
1863
- if (isNodeList(element)) {
1855
+ if (DOMUtilsCommonUtils.isNodeList(element)) {
1864
1856
  // 设置
1865
1857
  element.forEach(($ele) => {
1866
1858
  DOMUtilsContext.fadeIn($ele as HTMLElement, duration, callback);
@@ -1913,7 +1905,7 @@ class DOMUtils extends DOMUtilsEvent {
1913
1905
  if (typeof element === "string") {
1914
1906
  element = DOMUtilsContext.selectorAll(element);
1915
1907
  }
1916
- if (isNodeList(element)) {
1908
+ if (DOMUtilsCommonUtils.isNodeList(element)) {
1917
1909
  // 设置
1918
1910
  element.forEach(($ele) => {
1919
1911
  DOMUtilsContext.fadeOut($ele as HTMLElement, duration, callback);
@@ -1957,7 +1949,7 @@ class DOMUtils extends DOMUtilsEvent {
1957
1949
  if (element == null) {
1958
1950
  return;
1959
1951
  }
1960
- if (isNodeList(element)) {
1952
+ if (DOMUtilsCommonUtils.isNodeList(element)) {
1961
1953
  // 设置
1962
1954
  element.forEach(($ele) => {
1963
1955
  DOMUtilsContext.toggle($ele as HTMLElement);
@@ -184,5 +184,12 @@ const DOMUtilsCommonUtils = {
184
184
  globalThis.clearInterval(timeId);
185
185
  }
186
186
  },
187
+ /**
188
+ * 判断是否是元素列表
189
+ * @param $ele
190
+ */
191
+ isNodeList($ele: any): $ele is any[] | NodeList {
192
+ return Array.isArray($ele) || $ele instanceof NodeList;
193
+ },
187
194
  };
188
195
  export { DOMUtilsCommonUtils };
@@ -1,4 +1,3 @@
1
- import { isNodeList } from "./DOMUtils";
2
1
  import { DOMUtilsCommonUtils } from "./DOMUtilsCommonUtils";
3
2
  import { DOMUtilsData } from "./DOMUtilsData";
4
3
  import { OriginPrototype } from "./DOMUtilsOriginPrototype";
@@ -279,13 +278,15 @@ export class DOMUtilsEvent {
279
278
  : elementItem;
280
279
  let findValue = selectorList.find((selectorItem) => {
281
280
  // 判断目标元素是否匹配选择器
282
- if (eventTarget?.matches(selectorItem)) {
281
+ if (DOMUtilsContext.matches(eventTarget, selectorItem)) {
283
282
  /* 当前目标可以被selector所匹配到 */
284
283
  return true;
285
284
  }
286
285
  /* 在上层与主元素之间寻找可以被selector所匹配到的 */
287
- let $closestMatches =
288
- eventTarget?.closest<HTMLElement>(selectorItem);
286
+ let $closestMatches = DOMUtilsContext.closest<HTMLElement>(
287
+ eventTarget,
288
+ selectorItem
289
+ );
289
290
  if ($closestMatches && totalParent?.contains($closestMatches)) {
290
291
  eventTarget = $closestMatches;
291
292
  return true;
@@ -910,7 +911,7 @@ export class DOMUtilsEvent {
910
911
  if (element == null) {
911
912
  return;
912
913
  }
913
- if (isNodeList(element)) {
914
+ if (DOMUtilsCommonUtils.isNodeList(element)) {
914
915
  // 设置
915
916
  element.forEach(($ele) => {
916
917
  DOMUtilsContext.click(
@@ -960,7 +961,7 @@ export class DOMUtilsEvent {
960
961
  if (element == null) {
961
962
  return;
962
963
  }
963
- if (isNodeList(element)) {
964
+ if (DOMUtilsCommonUtils.isNodeList(element)) {
964
965
  // 设置
965
966
  element.forEach(($ele) => {
966
967
  DOMUtilsContext.focus(
@@ -1015,7 +1016,7 @@ export class DOMUtilsEvent {
1015
1016
  if (element == null) {
1016
1017
  return;
1017
1018
  }
1018
- if (isNodeList(element)) {
1019
+ if (DOMUtilsCommonUtils.isNodeList(element)) {
1019
1020
  // 设置
1020
1021
  element.forEach(($ele) => {
1021
1022
  DOMUtilsContext.focus(
@@ -1064,7 +1065,7 @@ export class DOMUtilsEvent {
1064
1065
  if (element == null) {
1065
1066
  return;
1066
1067
  }
1067
- if (isNodeList(element)) {
1068
+ if (DOMUtilsCommonUtils.isNodeList(element)) {
1068
1069
  // 设置
1069
1070
  element.forEach(($ele) => {
1070
1071
  DOMUtilsContext.hover($ele as HTMLElement, handler, option);
@@ -1101,7 +1102,7 @@ export class DOMUtilsEvent {
1101
1102
  if (typeof element === "string") {
1102
1103
  element = DOMUtilsContext.selectorAll(element);
1103
1104
  }
1104
- if (isNodeList(element)) {
1105
+ if (DOMUtilsCommonUtils.isNodeList(element)) {
1105
1106
  // 设置
1106
1107
  element.forEach(($ele) => {
1107
1108
  DOMUtilsContext.keyup($ele as HTMLElement, handler, option);
@@ -1137,7 +1138,7 @@ export class DOMUtilsEvent {
1137
1138
  if (typeof element === "string") {
1138
1139
  element = DOMUtilsContext.selectorAll(element);
1139
1140
  }
1140
- if (isNodeList(element)) {
1141
+ if (DOMUtilsCommonUtils.isNodeList(element)) {
1141
1142
  // 设置
1142
1143
  element.forEach(($ele) => {
1143
1144
  DOMUtilsContext.keydown($ele as HTMLElement, handler, option);
@@ -1173,7 +1174,7 @@ export class DOMUtilsEvent {
1173
1174
  if (typeof element === "string") {
1174
1175
  element = DOMUtilsContext.selectorAll(element);
1175
1176
  }
1176
- if (isNodeList(element)) {
1177
+ if (DOMUtilsCommonUtils.isNodeList(element)) {
1177
1178
  // 设置
1178
1179
  element.forEach(($ele) => {
1179
1180
  DOMUtilsContext.keypress($ele as HTMLElement, handler, option);
@@ -1299,7 +1300,7 @@ export class DOMUtilsEvent {
1299
1300
  * + :contains([text]) 作用: 找到包含指定文本内容的指定元素
1300
1301
  * + :empty 作用:找到既没有文本内容也没有子元素的指定元素
1301
1302
  * + :regexp([text]) 作用: 找到符合正则表达式的内容的指定元素
1302
- * @param selector
1303
+ * @param selector 选择器
1303
1304
  * @example
1304
1305
  * DOMUtils.selector("div:contains('测试')")
1305
1306
  * > div.xxx
@@ -1323,7 +1324,7 @@ export class DOMUtilsEvent {
1323
1324
  * + :contains([text]) 作用: 找到包含指定文本内容的指定元素
1324
1325
  * + :empty 作用:找到既没有文本内容也没有子元素的指定元素
1325
1326
  * + :regexp([text]) 作用: 找到符合正则表达式的内容的指定元素
1326
- * @param selector
1327
+ * @param selector 选择器
1327
1328
  * @example
1328
1329
  * DOMUtils.selectorAll("div:contains('测试')")
1329
1330
  * > [div.xxx]
@@ -1394,4 +1395,168 @@ export class DOMUtilsEvent {
1394
1395
  );
1395
1396
  }
1396
1397
  }
1398
+ /**
1399
+ * 匹配元素,可使用以下的额外语法
1400
+ *
1401
+ * + :contains([text]) 作用: 找到包含指定文本内容的指定元素
1402
+ * + :empty 作用:找到既没有文本内容也没有子元素的指定元素
1403
+ * + :regexp([text]) 作用: 找到符合正则表达式的内容的指定元素
1404
+ * @param $el 元素
1405
+ * @param selector 选择器
1406
+ * @example
1407
+ * DOMUtils.matches("div:contains('测试')")
1408
+ * > true
1409
+ * @example
1410
+ * DOMUtils.matches("div:empty")
1411
+ * > true
1412
+ * @example
1413
+ * DOMUtils.matches("div:regexp('^xxxx$')")
1414
+ * > true
1415
+ * @example
1416
+ * DOMUtils.matches("div:regexp(/^xxx/ig)")
1417
+ * > false
1418
+ */
1419
+ matches(
1420
+ $el: HTMLElement | Element | null | undefined,
1421
+ selector: string
1422
+ ): boolean {
1423
+ selector = selector.trim();
1424
+ if ($el == null) {
1425
+ return false;
1426
+ }
1427
+
1428
+ if (selector.match(/[^\s]{1}:empty$/gi)) {
1429
+ // empty 语法
1430
+ selector = selector.replace(/:empty$/gi, "");
1431
+ return $el.matches(selector) && $el?.innerHTML?.trim() === "";
1432
+ } else if (
1433
+ selector.match(/[^\s]{1}:contains\("(.*)"\)$/i) ||
1434
+ selector.match(/[^\s]{1}:contains\('(.*)'\)$/i)
1435
+ ) {
1436
+ // contains 语法
1437
+ let textMatch = selector.match(/:contains\(("|')(.*)("|')\)$/i);
1438
+ let text = textMatch![2];
1439
+ selector = selector.replace(/:contains\(("|')(.*)("|')\)$/gi, "");
1440
+ // @ts-ignore
1441
+ let content = $el?.textContent || $el?.innerText;
1442
+ if (typeof content !== "string") {
1443
+ content = "";
1444
+ }
1445
+ return $el.matches(selector) && content?.includes(text);
1446
+ } else if (
1447
+ selector.match(/[^\s]{1}:regexp\("(.*)"\)$/i) ||
1448
+ selector.match(/[^\s]{1}:regexp\('(.*)'\)$/i)
1449
+ ) {
1450
+ // regexp 语法
1451
+ let textMatch = selector.match(/:regexp\(("|')(.*)("|')\)$/i);
1452
+ let pattern = textMatch![2];
1453
+ let flagMatch = pattern.match(/("|'),[\s]*("|')([igm]{0,3})$/i);
1454
+ let flags = "";
1455
+ if (flagMatch) {
1456
+ pattern = pattern.replace(/("|'),[\s]*("|')([igm]{0,3})$/gi, "");
1457
+ flags = flagMatch[3];
1458
+ }
1459
+ let regexp = new RegExp(pattern, flags);
1460
+ selector = selector.replace(/:regexp\(("|')(.*)("|')\)$/gi, "");
1461
+ // @ts-ignore
1462
+ let content = $el?.textContent || $el?.innerText;
1463
+ if (typeof content !== "string") {
1464
+ content = "";
1465
+ }
1466
+ return $el.matches(selector) && Boolean(content?.match(regexp));
1467
+ } else {
1468
+ // 普通语法
1469
+ return $el.matches(selector);
1470
+ }
1471
+ }
1472
+ /**
1473
+ * 根据选择器获取上层元素,可使用以下的额外语法
1474
+ *
1475
+ * + :contains([text]) 作用: 找到包含指定文本内容的指定元素
1476
+ * + :empty 作用:找到既没有文本内容也没有子元素的指定元素
1477
+ * + :regexp([text]) 作用: 找到符合正则表达式的内容的指定元素
1478
+ * @param $el 元素
1479
+ * @param selector 选择器
1480
+ * @example
1481
+ * DOMUtils.closest("div:contains('测试')")
1482
+ * > div.xxx
1483
+ * @example
1484
+ * DOMUtils.closest("div:empty")
1485
+ * > div.xxx
1486
+ * @example
1487
+ * DOMUtils.closest("div:regexp('^xxxx$')")
1488
+ * > div.xxxx
1489
+ * @example
1490
+ * DOMUtils.closest("div:regexp(/^xxx/ig)")
1491
+ * > null
1492
+ */
1493
+ closest<K extends keyof HTMLElementTagNameMap>(
1494
+ $el: HTMLElement | Element,
1495
+ selector: string
1496
+ ): HTMLElementTagNameMap[K] | null;
1497
+ closest<E extends Element = Element>(
1498
+ $el: HTMLElement | Element,
1499
+ selector: string
1500
+ ): E | null;
1501
+ closest<E extends Element = Element>(
1502
+ $el: HTMLElement | Element,
1503
+ selector: string
1504
+ ): E | null {
1505
+ selector = selector.trim();
1506
+
1507
+ if (selector.match(/[^\s]{1}:empty$/gi)) {
1508
+ // empty 语法
1509
+ selector = selector.replace(/:empty$/gi, "");
1510
+ let $closest = $el?.closest<E>(selector);
1511
+ if ($closest && $closest?.innerHTML?.trim() === "") {
1512
+ return $closest;
1513
+ }
1514
+ return null;
1515
+ } else if (
1516
+ selector.match(/[^\s]{1}:contains\("(.*)"\)$/i) ||
1517
+ selector.match(/[^\s]{1}:contains\('(.*)'\)$/i)
1518
+ ) {
1519
+ // contains 语法
1520
+ let textMatch = selector.match(/:contains\(("|')(.*)("|')\)$/i);
1521
+ let text = textMatch![2];
1522
+ selector = selector.replace(/:contains\(("|')(.*)("|')\)$/gi, "");
1523
+ let $closest = $el?.closest<E>(selector);
1524
+ if ($closest) {
1525
+ // @ts-ignore
1526
+ let content = $el?.textContent || $el?.innerText;
1527
+ if (typeof content === "string" && content.includes(text)) {
1528
+ return $closest;
1529
+ }
1530
+ }
1531
+ return null;
1532
+ } else if (
1533
+ selector.match(/[^\s]{1}:regexp\("(.*)"\)$/i) ||
1534
+ selector.match(/[^\s]{1}:regexp\('(.*)'\)$/i)
1535
+ ) {
1536
+ // regexp 语法
1537
+ let textMatch = selector.match(/:regexp\(("|')(.*)("|')\)$/i);
1538
+ let pattern = textMatch![2];
1539
+ let flagMatch = pattern.match(/("|'),[\s]*("|')([igm]{0,3})$/i);
1540
+ let flags = "";
1541
+ if (flagMatch) {
1542
+ pattern = pattern.replace(/("|'),[\s]*("|')([igm]{0,3})$/gi, "");
1543
+ flags = flagMatch[3];
1544
+ }
1545
+ let regexp = new RegExp(pattern, flags);
1546
+ selector = selector.replace(/:regexp\(("|')(.*)("|')\)$/gi, "");
1547
+ let $closest = $el?.closest<E>(selector);
1548
+ if ($closest) {
1549
+ // @ts-ignore
1550
+ let content = $el?.textContent || $el?.innerText;
1551
+ if (typeof content === "string" && content.match(regexp)) {
1552
+ return $closest;
1553
+ }
1554
+ }
1555
+ return null;
1556
+ } else {
1557
+ // 普通语法
1558
+ let $closest = $el?.closest<E>(selector);
1559
+ return $closest;
1560
+ }
1561
+ }
1397
1562
  }