@whitesev/pops 1.4.0 → 1.5.0

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.
Files changed (105) hide show
  1. package/dist/index.amd.js.map +1 -1
  2. package/dist/index.cjs.js.map +1 -1
  3. package/dist/index.esm.js.map +1 -1
  4. package/dist/index.iife.js.map +1 -1
  5. package/dist/index.system.js.map +1 -1
  6. package/dist/index.umd.js.map +1 -1
  7. package/package.json +50 -48
  8. package/src/Config.ts +3 -0
  9. package/src/Core.ts +45 -0
  10. package/src/Pops.ts +340 -0
  11. package/src/components/alert/index.css +45 -0
  12. package/src/components/alert/index.ts +216 -0
  13. package/src/components/alert/indexType.ts +30 -0
  14. package/src/components/confirm/index.css +45 -0
  15. package/src/components/confirm/index.ts +264 -0
  16. package/src/components/confirm/indexType.ts +17 -0
  17. package/src/components/drawer/index.css +47 -0
  18. package/src/components/drawer/index.ts +338 -0
  19. package/src/components/drawer/indexType.ts +53 -0
  20. package/src/components/folder/folderIcon.ts +28 -0
  21. package/src/components/folder/index.css +291 -0
  22. package/src/components/folder/index.ts +1111 -0
  23. package/src/components/folder/indexType.ts +87 -0
  24. package/src/components/iframe/index.css +90 -0
  25. package/src/components/iframe/index.ts +415 -0
  26. package/src/components/iframe/indexType.ts +144 -0
  27. package/src/components/loading/index.css +60 -0
  28. package/src/components/loading/index.ts +123 -0
  29. package/src/components/loading/indexType.ts +31 -0
  30. package/src/components/panel/buttonType.ts +60 -0
  31. package/src/components/panel/commonType.ts +50 -0
  32. package/src/components/panel/deepMenuType.ts +59 -0
  33. package/src/components/panel/formsType.ts +32 -0
  34. package/src/components/panel/index.css +754 -0
  35. package/src/components/panel/index.ts +2435 -0
  36. package/src/components/panel/indexType.ts +107 -0
  37. package/src/components/panel/inputType.ts +65 -0
  38. package/src/components/panel/ownType.ts +28 -0
  39. package/src/components/panel/selectType.ts +80 -0
  40. package/src/components/panel/sliderType.ts +59 -0
  41. package/src/components/panel/switchType.ts +43 -0
  42. package/src/components/panel/textareaType.ts +54 -0
  43. package/src/components/prompt/index.css +60 -0
  44. package/src/components/prompt/index.ts +293 -0
  45. package/src/components/prompt/indexType.ts +47 -0
  46. package/src/components/rightClickMenu/index.ts +729 -0
  47. package/src/components/rightClickMenu/indexType.ts +89 -0
  48. package/src/components/searchSuggestion/index.css +0 -0
  49. package/src/components/searchSuggestion/index.ts +656 -0
  50. package/src/components/searchSuggestion/indexType.ts +238 -0
  51. package/src/components/tooltip/index.css +171 -0
  52. package/src/components/tooltip/index.ts +358 -0
  53. package/src/components/tooltip/indexType.ts +95 -0
  54. package/src/css/animation.css +2240 -0
  55. package/src/css/button.css +290 -0
  56. package/src/css/common.css +24 -0
  57. package/src/css/index.css +135 -0
  58. package/src/css/ninePalaceGridPosition.css +50 -0
  59. package/src/css/scrollbar.css +18 -0
  60. package/src/handler/PopsElementHandler.ts +353 -0
  61. package/src/handler/PopsHandler.ts +659 -0
  62. package/src/svg/arrowLeft.svg +4 -0
  63. package/src/svg/arrowRight.svg +4 -0
  64. package/src/svg/chromeFilled.svg +14 -0
  65. package/src/svg/circleClose.svg +8 -0
  66. package/src/svg/close.svg +5 -0
  67. package/src/svg/cpu.svg +8 -0
  68. package/src/svg/delete.svg +5 -0
  69. package/src/svg/documentCopy.svg +5 -0
  70. package/src/svg/edit.svg +8 -0
  71. package/src/svg/eleme.svg +5 -0
  72. package/src/svg/elemePlus.svg +5 -0
  73. package/src/svg/headset.svg +5 -0
  74. package/src/svg/hide.svg +8 -0
  75. package/src/svg/keyboard.svg +8 -0
  76. package/src/svg/loading.svg +5 -0
  77. package/src/svg/max.svg +5 -0
  78. package/src/svg/min.svg +5 -0
  79. package/src/svg/mise.svg +5 -0
  80. package/src/svg/monitor.svg +5 -0
  81. package/src/svg/next.svg +5 -0
  82. package/src/svg/picture.svg +8 -0
  83. package/src/svg/prev.svg +5 -0
  84. package/src/svg/search.svg +5 -0
  85. package/src/svg/share.svg +5 -0
  86. package/src/svg/upload.svg +5 -0
  87. package/src/svg/videoPause.svg +5 -0
  88. package/src/svg/videoPlay.svg +5 -0
  89. package/src/svg/view.svg +5 -0
  90. package/src/types/PopsDOMUtilsEventType.d.ts +246 -0
  91. package/src/types/animation.d.ts +19 -0
  92. package/src/types/button.d.ts +226 -0
  93. package/src/types/components.d.ts +197 -0
  94. package/src/types/event.d.ts +62 -0
  95. package/src/types/global.d.ts +11 -0
  96. package/src/types/icon.d.ts +32 -0
  97. package/src/types/layer.d.ts +20 -0
  98. package/src/types/main.d.ts +136 -0
  99. package/src/types/mask.d.ts +35 -0
  100. package/src/types/position.d.ts +60 -0
  101. package/src/utils/AnyTouch.js +1394 -0
  102. package/src/utils/PopsDOMUtils.ts +2013 -0
  103. package/src/utils/PopsInstanceUtils.ts +685 -0
  104. package/src/utils/PopsMathUtils.ts +77 -0
  105. package/src/utils/PopsUtils.ts +380 -0
@@ -0,0 +1,2013 @@
1
+ import type {
2
+ ParseHTMLReturnType,
3
+ PopsDOMUtilsCreateElementAttributesMap,
4
+ } from "../types/PopsDOMUtilsEventType";
5
+ import { SymbolEvents } from "../Config";
6
+ import { OriginPrototype, PopsCore } from "../Core";
7
+ import type {
8
+ PopsDOMUtils_Event,
9
+ PopsDOMUtils_EventType,
10
+ PopsDOMUtilsElementEventType,
11
+ PopsDOMUtilsEventListenerOptionsAttribute,
12
+ } from "../types/PopsDOMUtilsEventType";
13
+ import { popsUtils } from "./PopsUtils";
14
+
15
+ class PopsDOMUtilsEvent {
16
+ /**
17
+ * 绑定事件
18
+ * @param element 需要绑定的元素|元素数组|window
19
+ * @param eventType 需要监听的事件
20
+ * @param callback 绑定事件触发的回调函数
21
+ * @param option
22
+ * + capture 表示事件是否在捕获阶段触发。默认为false,即在冒泡阶段触发
23
+ * + once 表示事件是否只触发一次。默认为false
24
+ * + passive 表示事件监听器是否不会调用preventDefault()。默认为false
25
+ * @example
26
+ * // 监听元素a.xx的click事件
27
+ * DOMUtils.on(document.querySelector("a.xx"),"click",(event)=>{
28
+ * console.log("事件触发",event)
29
+ * })
30
+ * DOMUtils.on("a.xx","click",(event)=>{
31
+ * console.log("事件触发",event)
32
+ * })
33
+ */
34
+ on(
35
+ element: PopsDOMUtilsElementEventType,
36
+ eventType: string | string[],
37
+ callback: (event: Event) => void,
38
+ option?: boolean | AddEventListenerOptions
39
+ ): void;
40
+ on<T extends PopsDOMUtils_EventType>(
41
+ element: PopsDOMUtilsElementEventType,
42
+ eventType: T | T[],
43
+ callback: (event: PopsDOMUtils_Event[T]) => void,
44
+ option?: boolean | AddEventListenerOptions
45
+ ): void;
46
+ /**
47
+ * 绑定事件
48
+ * @param element 需要绑定的元素|元素数组|window
49
+ * @param eventType 需要监听的事件
50
+ * @param callback 绑定事件触发的回调函数
51
+ * @param option
52
+ * + capture 表示事件是否在捕获阶段触发。默认为false,即在冒泡阶段触发
53
+ * + once 表示事件是否只触发一次。默认为false
54
+ * + passive 表示事件监听器是否不会调用preventDefault()。默认为false
55
+ * @example
56
+ * // 监听元素a.xx的click事件
57
+ * DOMUtils.on(document.querySelector("a.xx"),"click",(event)=>{
58
+ * console.log("事件触发",event)
59
+ * })
60
+ * DOMUtils.on("a.xx","click",(event)=>{
61
+ * console.log("事件触发",event)
62
+ * })
63
+ */
64
+ on<T extends Event>(
65
+ element: PopsDOMUtilsElementEventType,
66
+ eventType: string,
67
+ callback: (event: T) => void,
68
+ option?: boolean | AddEventListenerOptions
69
+ ): void;
70
+ /**
71
+ * 绑定事件
72
+ * @param element 需要绑定的元素|元素数组|window
73
+ * @param eventType 需要监听的事件
74
+ * @param selector 子元素选择器
75
+ * @param callback 绑定事件触发的回调函数
76
+ * @param option
77
+ * + capture 表示事件是否在捕获阶段触发。默认为false,即在冒泡阶段触发
78
+ * + once 表示事件是否只触发一次。默认为false
79
+ * + passive 表示事件监听器是否不会调用preventDefault()。默认为false
80
+ * @example
81
+ * // 监听元素a.xx的click、tap、hover事件
82
+ * DOMUtils.on(document.querySelector("a.xx"),"click tap hover",(event)=>{
83
+ * console.log("事件触发",event)
84
+ * })
85
+ * DOMUtils.on("a.xx",["click","tap","hover"],(event)=>{
86
+ * console.log("事件触发",event)
87
+ * })
88
+ * @example
89
+ * // 监听全局document下的子元素a.xx的click事件
90
+ * DOMUtils.on(document,"click tap hover","a.xx",(event)=>{
91
+ * console.log("事件触发",event)
92
+ * })
93
+ */
94
+ on<T extends PopsDOMUtils_EventType>(
95
+ element: PopsDOMUtilsElementEventType,
96
+ eventType: T | T[],
97
+ selector: string | undefined | null,
98
+ callback: (event: PopsDOMUtils_Event[T]) => void,
99
+ option?: boolean | AddEventListenerOptions
100
+ ): void;
101
+ on<T extends Event>(
102
+ element: PopsDOMUtilsElementEventType,
103
+ eventType: string | string[],
104
+ selector: string | undefined | null,
105
+ callback: (event: T) => void,
106
+ option?: boolean | AddEventListenerOptions
107
+ ): void;
108
+ /**
109
+ * 绑定事件
110
+ * @param element 需要绑定的元素|元素数组|window
111
+ * @param eventType 需要监听的事件
112
+ * @param selector 子元素选择器
113
+ * @param callback 绑定事件触发的回调函数
114
+ * @param option
115
+ * + capture 表示事件是否在捕获阶段触发。默认为false,即在冒泡阶段触发
116
+ * + once 表示事件是否只触发一次。默认为false
117
+ * + passive 表示事件监听器是否不会调用preventDefault()。默认为false
118
+ * @example
119
+ * // 监听元素a.xx的click、tap、hover事件
120
+ * DOMUtils.on(document.querySelector("a.xx"),"click tap hover",(event)=>{
121
+ * console.log("事件触发",event)
122
+ * })
123
+ * DOMUtils.on("a.xx",["click","tap","hover"],(event)=>{
124
+ * console.log("事件触发",event)
125
+ * })
126
+ * @example
127
+ * // 监听全局document下的子元素a.xx的click事件
128
+ * DOMUtils.on(document,"click tap hover","a.xx",(event)=>{
129
+ * console.log("事件触发",event)
130
+ * })
131
+ */
132
+ on<T extends Event>(
133
+ element: PopsDOMUtilsElementEventType,
134
+ eventType: string,
135
+ selector: string | undefined | null,
136
+ callback: (event: T) => void,
137
+ option?: boolean | AddEventListenerOptions
138
+ ): void;
139
+ on<T extends Event>(
140
+ element:
141
+ | HTMLElement
142
+ | string
143
+ | NodeList
144
+ | HTMLElement[]
145
+ | Window
146
+ | Document
147
+ | Element
148
+ | null
149
+ | typeof globalThis,
150
+ eventType: PopsDOMUtils_EventType | PopsDOMUtils_EventType[] | string,
151
+ selector: string | undefined | ((event: T) => void) | null,
152
+ callback?: ((event: T) => void) | boolean | AddEventListenerOptions,
153
+ option?: boolean | AddEventListenerOptions
154
+ ) {
155
+ /**
156
+ * 获取option配置
157
+ * @param args
158
+ * @param startIndex
159
+ * @param option
160
+ */
161
+ function getOption(
162
+ args: IArguments,
163
+ startIndex: number,
164
+ option: AddEventListenerOptions
165
+ ) {
166
+ if (typeof args[startIndex] === "boolean") {
167
+ option.capture = args[startIndex];
168
+ if (typeof args[startIndex + 1] === "boolean") {
169
+ option.once = args[startIndex + 1];
170
+ }
171
+ if (typeof args[startIndex + 2] === "boolean") {
172
+ option.passive = args[startIndex + 2];
173
+ }
174
+ } else if (
175
+ typeof args[startIndex] === "object" &&
176
+ ("capture" in args[startIndex] ||
177
+ "once" in args[startIndex] ||
178
+ "passive" in args[startIndex])
179
+ ) {
180
+ option.capture = args[startIndex].capture;
181
+ option.once = args[startIndex].once;
182
+ option.passive = args[startIndex].passive;
183
+ }
184
+ return option;
185
+ }
186
+
187
+ let DOMUtilsContext = this;
188
+ let args = arguments;
189
+ if (typeof element === "string") {
190
+ element = PopsCore.document.querySelectorAll(element);
191
+ }
192
+ if (element == null) {
193
+ return;
194
+ }
195
+ let elementList: HTMLElement[] = [];
196
+ if (element instanceof NodeList || Array.isArray(element)) {
197
+ element = element as HTMLElement[];
198
+ elementList = [...element];
199
+ } else {
200
+ elementList.push(element as HTMLElement);
201
+ }
202
+
203
+ let eventTypeList: string[] = [];
204
+ if (Array.isArray(eventType)) {
205
+ eventTypeList = eventTypeList.concat(eventType as string[]);
206
+ } else if (typeof eventType === "string") {
207
+ eventTypeList = eventTypeList.concat(eventType.split(" "));
208
+ }
209
+ let _selector_: string | undefined = selector as any;
210
+ let _callback_: (event: T) => void = callback as any;
211
+ let _option_: AddEventListenerOptions = {
212
+ capture: false,
213
+ once: false,
214
+ passive: false,
215
+ };
216
+ if (typeof selector === "function") {
217
+ /* 这是为没有selector的情况 */
218
+ _selector_ = void 0;
219
+ _callback_ = selector;
220
+ _option_ = getOption(args, 3, _option_);
221
+ } else {
222
+ /* 这是存在selector的情况 */
223
+ _option_ = getOption(args, 4, _option_);
224
+ }
225
+ /**
226
+ * 如果是once,那么删除该监听和元素上的事件和监听
227
+ */
228
+ function checkOptionOnceToRemoveEventListener() {
229
+ if (_option_.once) {
230
+ DOMUtilsContext.off(
231
+ element,
232
+ eventType as any,
233
+ selector as any,
234
+ callback as any,
235
+ option
236
+ );
237
+ }
238
+ }
239
+ elementList.forEach((elementItem) => {
240
+ function ownCallBack(event: Event) {
241
+ let target = event.target as HTMLElement;
242
+ if (_selector_) {
243
+ /* 存在自定义子元素选择器 */
244
+ let totalParent = popsUtils.isWin(elementItem)
245
+ ? PopsCore.document.documentElement
246
+ : elementItem;
247
+ if (target.matches(_selector_)) {
248
+ /* 当前目标可以被selector所匹配到 */
249
+ _callback_.call(target, event as any);
250
+ checkOptionOnceToRemoveEventListener();
251
+ } else if (
252
+ target.closest(_selector_) &&
253
+ totalParent.contains(target.closest(_selector_))
254
+ ) {
255
+ /* 在上层与主元素之间寻找可以被selector所匹配到的 */
256
+ let closestElement = target.closest(_selector_);
257
+ /* event的target值不能直接修改 */
258
+ OriginPrototype.Object.defineProperty(event, "target", {
259
+ get() {
260
+ return closestElement;
261
+ },
262
+ });
263
+ _callback_.call(closestElement, event as any);
264
+ checkOptionOnceToRemoveEventListener();
265
+ }
266
+ } else {
267
+ _callback_.call(elementItem, event as any);
268
+ checkOptionOnceToRemoveEventListener();
269
+ }
270
+ }
271
+
272
+ /* 遍历事件名设置元素事件 */
273
+ eventTypeList.forEach((eventName) => {
274
+ elementItem.addEventListener(eventName, ownCallBack, _option_);
275
+
276
+ if (_callback_ && (_callback_ as any).delegate) {
277
+ elementItem.setAttribute("data-delegate", _selector_ as string);
278
+ }
279
+ /* 获取对象上的事件 */
280
+ let elementEvents = (elementItem as any)[SymbolEvents] || {};
281
+ /* 初始化对象上的xx事件 */
282
+ elementEvents[eventName] = elementEvents[eventName] || [];
283
+ elementEvents[eventName].push({
284
+ selector: _selector_,
285
+ option: _option_,
286
+ callback: ownCallBack,
287
+ originCallBack: _callback_,
288
+ });
289
+ /* 覆盖事件 */
290
+ (elementItem as any)[SymbolEvents] = elementEvents;
291
+ });
292
+ });
293
+ }
294
+ /**
295
+ * 取消绑定事件
296
+ * @param element 需要取消绑定的元素|元素数组
297
+ * @param eventType 需要取消监听的事件
298
+ * @param callback 通过DOMUtils.on绑定的事件函数
299
+ * @param option
300
+ * + capture 如果在添加事件监听器时指定了useCapture为true,则在移除事件监听器时也必须指定为true
301
+ * @param filter (可选)过滤函数,对元素属性上的事件进行过滤出想要删除的事件
302
+ * @example
303
+ * // 取消监听元素a.xx的click事件
304
+ * DOMUtils.off(document.querySelector("a.xx"),"click")
305
+ * DOMUtils.off("a.xx","click")
306
+ */
307
+ off(
308
+ element: PopsDOMUtilsElementEventType,
309
+ eventType: string | string[],
310
+ callback?: (event: Event) => void,
311
+ option?: boolean | AddEventListenerOptions,
312
+ filter?: (
313
+ value: PopsDOMUtilsEventListenerOptionsAttribute,
314
+ index: number,
315
+ array: PopsDOMUtilsEventListenerOptionsAttribute[]
316
+ ) => boolean
317
+ ): void;
318
+ off<T extends PopsDOMUtils_EventType>(
319
+ element: PopsDOMUtilsElementEventType,
320
+ eventType: T | T[],
321
+ callback?: (event: PopsDOMUtils_Event[T]) => void,
322
+ option?: boolean | AddEventListenerOptions,
323
+ filter?: (
324
+ value: PopsDOMUtilsEventListenerOptionsAttribute,
325
+ index: number,
326
+ array: PopsDOMUtilsEventListenerOptionsAttribute[]
327
+ ) => boolean
328
+ ): void;
329
+ /**
330
+ * 取消绑定事件
331
+ * @param element 需要取消绑定的元素|元素数组
332
+ * @param eventType 需要取消监听的事件
333
+ * @param callback 通过DOMUtils.on绑定的事件函数
334
+ * @param option
335
+ * + capture 如果在添加事件监听器时指定了useCapture为true,则在移除事件监听器时也必须指定为true
336
+ * @param filter (可选)过滤函数,对元素属性上的事件进行过滤出想要删除的事件
337
+ * @example
338
+ * // 取消监听元素a.xx的click事件
339
+ * DOMUtils.off(document.querySelector("a.xx"),"click")
340
+ * DOMUtils.off("a.xx","click")
341
+ */
342
+ off<T extends Event>(
343
+ element: PopsDOMUtilsElementEventType,
344
+ eventType: string,
345
+ callback?: (event: T) => void,
346
+ option?: boolean | AddEventListenerOptions,
347
+ filter?: (
348
+ value: PopsDOMUtilsEventListenerOptionsAttribute,
349
+ index: number,
350
+ array: PopsDOMUtilsEventListenerOptionsAttribute[]
351
+ ) => boolean
352
+ ): void;
353
+ /**
354
+ * 取消绑定事件
355
+ * @param element 需要取消绑定的元素|元素数组
356
+ * @param eventType 需要取消监听的事件
357
+ * @param selector 子元素选择器
358
+ * @param callback 通过DOMUtils.on绑定的事件函数
359
+ * @param option
360
+ * + capture 如果在添加事件监听器时指定了useCapture为true,则在移除事件监听器时也必须指定为true
361
+ * @param filter (可选)过滤函数,对元素属性上的事件进行过滤出想要删除的事件
362
+ * @example
363
+ * // 取消监听元素a.xx的click、tap、hover事件
364
+ * DOMUtils.off(document.querySelector("a.xx"),"click tap hover")
365
+ * DOMUtils.off("a.xx",["click","tap","hover"])
366
+ */
367
+ off<T extends PopsDOMUtils_EventType>(
368
+ element: PopsDOMUtilsElementEventType,
369
+ eventType: T | T[],
370
+ selector?: string | undefined,
371
+ callback?: (event: PopsDOMUtils_Event[T]) => void,
372
+ option?: boolean | AddEventListenerOptions,
373
+ filter?: (
374
+ value: PopsDOMUtilsEventListenerOptionsAttribute,
375
+ index: number,
376
+ array: PopsDOMUtilsEventListenerOptionsAttribute[]
377
+ ) => boolean
378
+ ): void;
379
+ /**
380
+ * 取消绑定事件
381
+ * @param element 需要取消绑定的元素|元素数组
382
+ * @param eventType 需要取消监听的事件
383
+ * @param selector 子元素选择器
384
+ * @param callback 通过DOMUtils.on绑定的事件函数
385
+ * @param option
386
+ * + capture 如果在添加事件监听器时指定了useCapture为true,则在移除事件监听器时也必须指定为true
387
+ * @param filter (可选)过滤函数,对元素属性上的事件进行过滤出想要删除的事件
388
+ * @example
389
+ * // 取消监听元素a.xx的click、tap、hover事件
390
+ * DOMUtils.off(document.querySelector("a.xx"),"click tap hover")
391
+ * DOMUtils.off("a.xx",["click","tap","hover"])
392
+ */
393
+ off<T extends Event>(
394
+ element: PopsDOMUtilsElementEventType,
395
+ eventType: string | string[],
396
+ selector?: string | undefined,
397
+ callback?: (event: T) => void,
398
+ option?: boolean | AddEventListenerOptions,
399
+ filter?: (
400
+ value: PopsDOMUtilsEventListenerOptionsAttribute,
401
+ index: number,
402
+ array: PopsDOMUtilsEventListenerOptionsAttribute[]
403
+ ) => boolean
404
+ ): void;
405
+ off<T extends Event>(
406
+ element:
407
+ | HTMLElement
408
+ | string
409
+ | NodeList
410
+ | HTMLElement[]
411
+ | Window
412
+ | Document
413
+ | Element
414
+ | null
415
+ | typeof globalThis,
416
+ eventType:
417
+ | PopsDOMUtils_EventType
418
+ | PopsDOMUtils_EventType[]
419
+ | string
420
+ | string[],
421
+ selector?: string | undefined | ((event: T) => void),
422
+ callback?: ((event: T) => void) | boolean | AddEventListenerOptions,
423
+ option?:
424
+ | boolean
425
+ | AddEventListenerOptions
426
+ | ((
427
+ value: PopsDOMUtilsEventListenerOptionsAttribute,
428
+ index: number,
429
+ array: PopsDOMUtilsEventListenerOptionsAttribute[]
430
+ ) => boolean),
431
+ filter?: (
432
+ value: PopsDOMUtilsEventListenerOptionsAttribute,
433
+ index: number,
434
+ array: PopsDOMUtilsEventListenerOptionsAttribute[]
435
+ ) => boolean
436
+ ) {
437
+ /**
438
+ * 获取option配置
439
+ * @param args1
440
+ * @param startIndex
441
+ * @param option
442
+ */
443
+ function getOption(
444
+ args1: IArguments,
445
+ startIndex: number,
446
+ option: EventListenerOptions
447
+ ) {
448
+ if (typeof args1[startIndex] === "boolean") {
449
+ option.capture = args1[startIndex];
450
+ } else if (
451
+ typeof args1[startIndex] === "object" &&
452
+ "capture" in args1[startIndex]
453
+ ) {
454
+ option.capture = args1[startIndex].capture;
455
+ }
456
+ return option;
457
+ }
458
+
459
+ let args = arguments;
460
+ if (typeof element === "string") {
461
+ element = PopsCore.document.querySelectorAll(element);
462
+ }
463
+ if (element == null) {
464
+ return;
465
+ }
466
+ let elementList: HTMLElement[] = [];
467
+ if (element instanceof NodeList || Array.isArray(element)) {
468
+ element = element as HTMLElement[];
469
+ elementList = [...element];
470
+ } else {
471
+ elementList.push(element as HTMLElement);
472
+ }
473
+ let eventTypeList: string[] = [];
474
+ if (Array.isArray(eventType)) {
475
+ eventTypeList = eventTypeList.concat(eventType as string[]);
476
+ } else if (typeof eventType === "string") {
477
+ eventTypeList = eventTypeList.concat(eventType.split(" "));
478
+ }
479
+ /**
480
+ * 子元素选择器
481
+ */
482
+ let _selector_: string | undefined = selector as any;
483
+ /**
484
+ * 事件的回调函数
485
+ */
486
+ let _callback_: (event: T) => void = callback as any;
487
+
488
+ /**
489
+ * 事件的配置
490
+ */
491
+ let _option_: EventListenerOptions = {
492
+ capture: false,
493
+ };
494
+ if (typeof selector === "function") {
495
+ /* 这是为没有selector的情况 */
496
+ _selector_ = void 0;
497
+ _callback_ = selector;
498
+ _option_ = getOption(args, 3, _option_);
499
+ } else {
500
+ _option_ = getOption(args, 4, _option_);
501
+ }
502
+ elementList.forEach((elementItem) => {
503
+ /* 获取对象上的事件 */
504
+ let elementEvents = (elementItem as any)[SymbolEvents] || {};
505
+ eventTypeList.forEach((eventName) => {
506
+ let handlers: PopsDOMUtilsEventListenerOptionsAttribute[] =
507
+ elementEvents[eventName] || [];
508
+ if (typeof filter === "function") {
509
+ handlers = handlers.filter(filter);
510
+ }
511
+ for (let index = 0; index < handlers.length; index++) {
512
+ let handler = handlers[index];
513
+ let flag = false;
514
+ if (!_selector_ || handler.selector === _selector_) {
515
+ /* selector不为空,进行selector判断 */
516
+ flag = true;
517
+ }
518
+ if (
519
+ !_callback_ ||
520
+ handler.callback === _callback_ ||
521
+ handler.originCallBack === _callback_
522
+ ) {
523
+ /* callback不为空,进行callback判断 */
524
+ flag = true;
525
+ }
526
+
527
+ if (flag) {
528
+ elementItem.removeEventListener(
529
+ eventName,
530
+ handler.callback,
531
+ _option_
532
+ );
533
+ handlers.splice(index--, 1);
534
+ }
535
+ }
536
+ if (handlers.length === 0) {
537
+ /* 如果没有任意的handler,那么删除该属性 */
538
+ popsUtils.delete(elementEvents, eventType);
539
+ }
540
+ });
541
+ (elementItem as any)[SymbolEvents] = elementEvents;
542
+ });
543
+ }
544
+ /**
545
+ * 取消绑定所有的事件
546
+ * @param element 需要取消绑定的元素|元素数组
547
+ * @param eventType (可选)需要取消监听的事件
548
+ */
549
+ offAll(element: PopsDOMUtilsElementEventType, eventType?: string): void;
550
+ /**
551
+ * 取消绑定所有的事件
552
+ * @param element 需要取消绑定的元素|元素数组
553
+ * @param eventType (可选)需要取消监听的事件
554
+ */
555
+ offAll(
556
+ element: PopsDOMUtilsElementEventType,
557
+ eventType?: PopsDOMUtils_EventType | PopsDOMUtils_EventType[]
558
+ ): void;
559
+ /**
560
+ * 取消绑定所有的事件
561
+ * @param element 需要取消绑定的元素|元素数组
562
+ * @param eventType (可选)需要取消监听的事件
563
+ */
564
+ offAll(
565
+ element: PopsDOMUtilsElementEventType,
566
+ eventType?: PopsDOMUtils_EventType | PopsDOMUtils_EventType[] | string
567
+ ) {
568
+ if (typeof element === "string") {
569
+ element = PopsCore.document.querySelectorAll(element);
570
+ }
571
+ if (element == null) {
572
+ return;
573
+ }
574
+ let elementList: HTMLElement[] = [];
575
+ if (element instanceof NodeList || Array.isArray(element)) {
576
+ elementList = [...(element as HTMLElement[])];
577
+ } else {
578
+ elementList.push(element as HTMLElement);
579
+ }
580
+
581
+ let eventTypeList: string[] = [];
582
+ if (Array.isArray(eventType)) {
583
+ eventTypeList = eventTypeList.concat(eventType as string[]);
584
+ } else if (typeof eventType === "string") {
585
+ eventTypeList = eventTypeList.concat(eventType.split(" "));
586
+ }
587
+ elementList.forEach((elementItem) => {
588
+ Object.getOwnPropertySymbols(elementItem).forEach((__symbolEvents) => {
589
+ if (!__symbolEvents.toString().startsWith("Symbol(events_")) {
590
+ return;
591
+ }
592
+ let elementEvents = (elementItem as any)[__symbolEvents] || {};
593
+ let iterEventNameList = eventTypeList.length
594
+ ? eventTypeList
595
+ : Object.keys(elementEvents);
596
+ iterEventNameList.forEach((eventName) => {
597
+ let handlers = elementEvents[eventName];
598
+ if (!handlers) {
599
+ return;
600
+ }
601
+ for (const handler of handlers) {
602
+ elementItem.removeEventListener(eventName, handler.callback, {
603
+ capture: handler["option"]["capture"],
604
+ });
605
+ }
606
+ popsUtils.delete((elementItem as any)[__symbolEvents], eventName);
607
+ });
608
+ });
609
+ });
610
+ }
611
+
612
+ /**
613
+ * 等待文档加载完成后执行指定的函数
614
+ * @param callback 需要执行的函数
615
+ * @example
616
+ * DOMUtils.ready(function(){
617
+ * console.log("文档加载完毕")
618
+ * })
619
+ */
620
+ ready<T extends Function>(callback: T) {
621
+ if (typeof callback !== "function") {
622
+ return;
623
+ }
624
+ /**
625
+ * 检测文档是否加载完毕
626
+ */
627
+ function checkDOMReadyState() {
628
+ try {
629
+ if (
630
+ document.readyState === "complete" ||
631
+ (document.readyState !== "loading" &&
632
+ !(document.documentElement as any).doScroll)
633
+ ) {
634
+ return true;
635
+ } else {
636
+ return false;
637
+ }
638
+ } catch (error) {
639
+ return false;
640
+ }
641
+ }
642
+ /**
643
+ * 成功加载完毕后触发的回调函数
644
+ */
645
+ function completed() {
646
+ removeDomReadyListener();
647
+ callback();
648
+ }
649
+
650
+ let targetList = [
651
+ {
652
+ target: PopsCore.document,
653
+ eventType: "DOMContentLoaded",
654
+ callback: completed,
655
+ },
656
+ {
657
+ target: PopsCore.window,
658
+ eventType: "load",
659
+ callback: completed,
660
+ },
661
+ ];
662
+ /**
663
+ * 添加监听
664
+ */
665
+ function addDomReadyListener() {
666
+ for (let index = 0; index < targetList.length; index++) {
667
+ let item = targetList[index];
668
+ item.target.addEventListener(item.eventType, item.callback);
669
+ }
670
+ }
671
+ /**
672
+ * 移除监听
673
+ */
674
+ function removeDomReadyListener() {
675
+ for (let index = 0; index < targetList.length; index++) {
676
+ let item = targetList[index];
677
+ item.target.removeEventListener(item.eventType, item.callback);
678
+ }
679
+ }
680
+ if (checkDOMReadyState()) {
681
+ /* 检查document状态 */
682
+ setTimeout(callback);
683
+ } else {
684
+ /* 添加监听 */
685
+ addDomReadyListener();
686
+ }
687
+ }
688
+ /**
689
+ * 主动触发事件
690
+ * @param element 需要触发的元素|元素数组|window
691
+ * @param eventType 需要触发的事件
692
+ * @param details 赋予触发的Event的额外属性,如果是Event类型,那么将自动代替默认new的Event对象
693
+ * @param useDispatchToTriggerEvent 是否使用dispatchEvent来触发事件,默认true
694
+ * @example
695
+ * // 触发元素a.xx的click事件
696
+ * DOMUtils.trigger(document.querySelector("a.xx"),"click")
697
+ * DOMUtils.trigger("a.xx","click")
698
+ * // 触发元素a.xx的click、tap、hover事件
699
+ * DOMUtils.trigger(document.querySelector("a.xx"),"click tap hover")
700
+ * DOMUtils.trigger("a.xx",["click","tap","hover"])
701
+ */
702
+ trigger(
703
+ element: HTMLElement | string | NodeList | any[] | Window | Document,
704
+ eventType: string | string[],
705
+ details?: object,
706
+ useDispatchToTriggerEvent?: boolean
707
+ ): void;
708
+ /**
709
+ * 主动触发事件
710
+ * @param element 需要触发的元素|元素数组|window
711
+ * @param eventType 需要触发的事件
712
+ * @param details 赋予触发的Event的额外属性,如果是Event类型,那么将自动代替默认new的Event对象
713
+ * @param useDispatchToTriggerEvent 是否使用dispatchEvent来触发事件,默认true
714
+ * @example
715
+ * // 触发元素a.xx的click事件
716
+ * DOMUtils.trigger(document.querySelector("a.xx"),"click")
717
+ * DOMUtils.trigger("a.xx","click")
718
+ * // 触发元素a.xx的click、tap、hover事件
719
+ * DOMUtils.trigger(document.querySelector("a.xx"),"click tap hover")
720
+ * DOMUtils.trigger("a.xx",["click","tap","hover"])
721
+ */
722
+ trigger(
723
+ element: HTMLElement | string | NodeList | any[] | Window | Document,
724
+ eventType: PopsDOMUtils_EventType | PopsDOMUtils_EventType[],
725
+ details?: object,
726
+ useDispatchToTriggerEvent?: boolean
727
+ ): void;
728
+ /**
729
+ * 主动触发事件
730
+ * @param element 需要触发的元素|元素数组|window
731
+ * @param eventType 需要触发的事件
732
+ * @param details 赋予触发的Event的额外属性,如果是Event类型,那么将自动代替默认new的Event对象
733
+ * @param useDispatchToTriggerEvent 是否使用dispatchEvent来触发事件,默认true
734
+ * @example
735
+ * // 触发元素a.xx的click事件
736
+ * DOMUtils.trigger(document.querySelector("a.xx"),"click")
737
+ * DOMUtils.trigger("a.xx","click")
738
+ * // 触发元素a.xx的click、tap、hover事件
739
+ * DOMUtils.trigger(document.querySelector("a.xx"),"click tap hover")
740
+ * DOMUtils.trigger("a.xx",["click","tap","hover"])
741
+ */
742
+ trigger(
743
+ element: HTMLElement | string | NodeList | any[] | Window | Document,
744
+ eventType: PopsDOMUtils_EventType | PopsDOMUtils_EventType[] | string,
745
+ details?: object,
746
+ useDispatchToTriggerEvent: boolean = true
747
+ ) {
748
+ if (typeof element === "string") {
749
+ element = PopsCore.document.querySelector(element) as HTMLElement;
750
+ }
751
+ if (element == null) {
752
+ return;
753
+ }
754
+ let elementList = [];
755
+ if (element instanceof NodeList || Array.isArray(element)) {
756
+ element = element as HTMLElement[];
757
+ elementList = [...element];
758
+ } else {
759
+ elementList = [element];
760
+ }
761
+ let eventTypeList: string[] = [];
762
+ if (Array.isArray(eventType)) {
763
+ eventTypeList = eventType as string[];
764
+ } else if (typeof eventType === "string") {
765
+ eventTypeList = eventType.split(" ");
766
+ }
767
+
768
+ elementList.forEach((elementItem) => {
769
+ /* 获取对象上的事件 */
770
+ let events = elementItem[SymbolEvents] || {};
771
+ eventTypeList.forEach((_eventType_) => {
772
+ let event: Event = null as any;
773
+ if (details && details instanceof Event) {
774
+ event = details;
775
+ } else {
776
+ event = new Event(_eventType_);
777
+ if (details) {
778
+ Object.keys(details).forEach((keyName) => {
779
+ (event as any)[keyName] = (details as any)[keyName];
780
+ });
781
+ }
782
+ }
783
+ if (useDispatchToTriggerEvent == false && _eventType_ in events) {
784
+ events[_eventType_].forEach((eventsItem: any) => {
785
+ eventsItem.callback(event);
786
+ });
787
+ } else {
788
+ elementItem.dispatchEvent(event);
789
+ }
790
+ });
791
+ });
792
+ }
793
+
794
+ /**
795
+ * 绑定或触发元素的click事件
796
+ * @param element 目标元素
797
+ * @param handler (可选)事件处理函数
798
+ * @param details (可选)赋予触发的Event的额外属性
799
+ * @param useDispatchToTriggerEvent (可选)是否使用dispatchEvent来触发事件,默认true
800
+ * @example
801
+ * // 触发元素a.xx的click事件
802
+ * DOMUtils.click(document.querySelector("a.xx"))
803
+ * DOMUtils.click("a.xx")
804
+ * DOMUtils.click("a.xx",function(){
805
+ * console.log("触发click事件成功")
806
+ * })
807
+ * */
808
+ click(
809
+ element: HTMLElement | string | Window,
810
+ handler?: (event: PopsDOMUtils_Event["click"]) => void,
811
+ details?: any,
812
+ useDispatchToTriggerEvent?: boolean
813
+ ) {
814
+ let DOMUtilsContext = this;
815
+ if (typeof element === "string") {
816
+ element = PopsCore.document.querySelector(element) as HTMLElement;
817
+ }
818
+ if (element == null) {
819
+ return;
820
+ }
821
+ if (handler == null) {
822
+ DOMUtilsContext.trigger(
823
+ element,
824
+ "click",
825
+ details,
826
+ useDispatchToTriggerEvent
827
+ );
828
+ } else {
829
+ DOMUtilsContext.on(element, "click", null, handler);
830
+ }
831
+ }
832
+ /**
833
+ * 绑定或触发元素的blur事件
834
+ * @param element 目标元素
835
+ * @param handler (可选)事件处理函数
836
+ * @param details (可选)赋予触发的Event的额外属性
837
+ * @param useDispatchToTriggerEvent (可选)是否使用dispatchEvent来触发事件,默认true
838
+ * @example
839
+ * // 触发元素a.xx的blur事件
840
+ * DOMUtils.blur(document.querySelector("a.xx"))
841
+ * DOMUtils.blur("a.xx")
842
+ * DOMUtils.blur("a.xx",function(){
843
+ * console.log("触发blur事件成功")
844
+ * })
845
+ * */
846
+ blur(
847
+ element: HTMLElement | string | Window,
848
+ handler?: (event: PopsDOMUtils_Event["blur"]) => void,
849
+ details?: object,
850
+ useDispatchToTriggerEvent?: boolean
851
+ ) {
852
+ let DOMUtilsContext = this;
853
+ if (typeof element === "string") {
854
+ element = PopsCore.document.querySelector(element) as HTMLElement;
855
+ }
856
+ if (element == null) {
857
+ return;
858
+ }
859
+ if (handler === null) {
860
+ DOMUtilsContext.trigger(
861
+ element,
862
+ "blur",
863
+ details,
864
+ useDispatchToTriggerEvent
865
+ );
866
+ } else {
867
+ DOMUtilsContext.on(
868
+ element,
869
+ "blur",
870
+ null,
871
+ handler as (event: Event) => void
872
+ );
873
+ }
874
+ }
875
+ /**
876
+ * 绑定或触发元素的focus事件
877
+ * @param element 目标元素
878
+ * @param handler (可选)事件处理函数
879
+ * @param details (可选)赋予触发的Event的额外属性
880
+ * @param useDispatchToTriggerEvent (可选)是否使用dispatchEvent来触发事件,默认true
881
+ * @example
882
+ * // 触发元素a.xx的focus事件
883
+ * DOMUtils.focus(document.querySelector("a.xx"))
884
+ * DOMUtils.focus("a.xx")
885
+ * DOMUtils.focus("a.xx",function(){
886
+ * console.log("触发focus事件成功")
887
+ * })
888
+ * */
889
+ focus(
890
+ element: HTMLElement | string | Window,
891
+ handler?: (event: PopsDOMUtils_Event["focus"]) => void,
892
+ details?: object,
893
+ useDispatchToTriggerEvent?: boolean
894
+ ) {
895
+ let DOMUtilsContext = this;
896
+ if (typeof element === "string") {
897
+ element = PopsCore.document.querySelector(element) as HTMLElement;
898
+ }
899
+ if (element == null) {
900
+ return;
901
+ }
902
+ if (handler == null) {
903
+ DOMUtilsContext.trigger(
904
+ element,
905
+ "focus",
906
+ details,
907
+ useDispatchToTriggerEvent
908
+ );
909
+ } else {
910
+ DOMUtilsContext.on(element, "focus", null, handler);
911
+ }
912
+ }
913
+ /**
914
+ * 当鼠标移入或移出元素时触发事件
915
+ * @param element 当前元素
916
+ * @param handler 事件处理函数
917
+ * @param option 配置
918
+ * @example
919
+ * // 监听a.xx元素的移入或移出
920
+ * DOMUtils.hover(document.querySelector("a.xx"),()=>{
921
+ * console.log("移入/移除");
922
+ * })
923
+ * DOMUtils.hover("a.xx",()=>{
924
+ * console.log("移入/移除");
925
+ * })
926
+ */
927
+ hover(
928
+ element: HTMLElement | string,
929
+ handler: (event: PopsDOMUtils_Event["hover"]) => void,
930
+ option?: boolean | AddEventListenerOptions
931
+ ) {
932
+ let DOMUtilsContext = this;
933
+ if (typeof element === "string") {
934
+ element = PopsCore.document.querySelector(element) as HTMLElement;
935
+ }
936
+ if (element == null) {
937
+ return;
938
+ }
939
+ DOMUtilsContext.on(element, "mouseenter", null, handler, option);
940
+ DOMUtilsContext.on(element, "mouseleave", null, handler, option);
941
+ }
942
+ /**
943
+ * 当按键松开时触发事件
944
+ * keydown - > keypress - > keyup
945
+ * @param target 当前元素
946
+ * @param handler 事件处理函数
947
+ * @param option 配置
948
+ * @example
949
+ * // 监听a.xx元素的按键松开
950
+ * DOMUtils.keyup(document.querySelector("a.xx"),()=>{
951
+ * console.log("按键松开");
952
+ * })
953
+ * DOMUtils.keyup("a.xx",()=>{
954
+ * console.log("按键松开");
955
+ * })
956
+ */
957
+ keyup(
958
+ target: HTMLElement | string | Window | typeof globalThis,
959
+ handler: (event: PopsDOMUtils_Event["keyup"]) => void,
960
+ option?: boolean | AddEventListenerOptions
961
+ ) {
962
+ let DOMUtilsContext = this;
963
+ if (target == null) {
964
+ return;
965
+ }
966
+ if (typeof target === "string") {
967
+ target = PopsCore.document.querySelector(target) as HTMLElement;
968
+ }
969
+ DOMUtilsContext.on(target, "keyup", null, handler, option);
970
+ }
971
+ /**
972
+ * 当按键按下时触发事件
973
+ * keydown - > keypress - > keyup
974
+ * @param target 目标
975
+ * @param handler 事件处理函数
976
+ * @param option 配置
977
+ * @example
978
+ * // 监听a.xx元素的按键按下
979
+ * DOMUtils.keydown(document.querySelector("a.xx"),()=>{
980
+ * console.log("按键按下");
981
+ * })
982
+ * DOMUtils.keydown("a.xx",()=>{
983
+ * console.log("按键按下");
984
+ * })
985
+ */
986
+ keydown(
987
+ target: HTMLElement | Window | typeof globalThis | string,
988
+ handler: (event: PopsDOMUtils_Event["keydown"]) => void,
989
+ option?: boolean | AddEventListenerOptions
990
+ ) {
991
+ let DOMUtilsContext = this;
992
+ if (target == null) {
993
+ return;
994
+ }
995
+ if (typeof target === "string") {
996
+ target = PopsCore.document.querySelector(target) as HTMLElement;
997
+ }
998
+ DOMUtilsContext.on(target, "keydown", null, handler, option);
999
+ }
1000
+ /**
1001
+ * 当按键按下时触发事件
1002
+ * keydown - > keypress - > keyup
1003
+ * @param target 目标
1004
+ * @param handler 事件处理函数
1005
+ * @param option 配置
1006
+ * @example
1007
+ * // 监听a.xx元素的按键按下
1008
+ * DOMUtils.keypress(document.querySelector("a.xx"),()=>{
1009
+ * console.log("按键按下");
1010
+ * })
1011
+ * DOMUtils.keypress("a.xx",()=>{
1012
+ * console.log("按键按下");
1013
+ * })
1014
+ */
1015
+ keypress(
1016
+ target: HTMLElement | Window | typeof globalThis | string,
1017
+ handler: (event: PopsDOMUtils_Event["keypress"]) => void,
1018
+ option?: boolean | AddEventListenerOptions
1019
+ ) {
1020
+ let DOMUtilsContext = this;
1021
+ if (target == null) {
1022
+ return;
1023
+ }
1024
+ if (typeof target === "string") {
1025
+ target = PopsCore.document.querySelector(target) as HTMLElement;
1026
+ }
1027
+ DOMUtilsContext.on(target, "keypress", null, handler, option);
1028
+ }
1029
+
1030
+ /**
1031
+ * 阻止事件传递
1032
+ * @param element 要进行处理的元素
1033
+ * @param eventNameList (可选)要阻止的事件名|列表
1034
+ * @param capture (可选)是否捕获,默认false
1035
+ * @example
1036
+ * Utils.preventEvent(document.querySelector("a"),"click")
1037
+ * @example
1038
+ * Utils.preventEvent(event);
1039
+ */
1040
+ preventEvent(event: Event): boolean;
1041
+ /**
1042
+ * 阻止事件传递
1043
+ * @param element 要进行处理的元素
1044
+ * @param eventNameList (可选)要阻止的事件名|列表
1045
+ * @param capture (可选)是否捕获,默认false
1046
+ * @example
1047
+ * Utils.preventEvent(document.querySelector("a"),"click")
1048
+ * @example
1049
+ * Utils.preventEvent(event);
1050
+ */
1051
+ preventEvent(
1052
+ element: HTMLElement,
1053
+ eventNameList?: string | string[],
1054
+ capture?: boolean
1055
+ ): boolean;
1056
+ preventEvent(
1057
+ element: HTMLElement | Event,
1058
+ eventNameList: string | string[] = [],
1059
+ capture?: boolean
1060
+ ): boolean | undefined {
1061
+ function stopEvent(event: Event) {
1062
+ /* 阻止事件的默认行为发生。例如,当点击一个链接时,浏览器会默认打开链接的URL */
1063
+ event?.preventDefault();
1064
+ /* 停止事件的传播,阻止它继续向更上层的元素冒泡,事件将不会再传播给其他的元素 */
1065
+ event?.stopPropagation();
1066
+ /* 阻止事件传播,并且还能阻止元素上的其他事件处理程序被触发 */
1067
+ event?.stopImmediatePropagation();
1068
+ return false;
1069
+ }
1070
+ if (arguments.length === 1) {
1071
+ /* 直接阻止事件 */
1072
+ return stopEvent(arguments[0]);
1073
+ } else {
1074
+ /* 添加对应的事件来阻止触发 */
1075
+ if (typeof eventNameList === "string") {
1076
+ eventNameList = [eventNameList];
1077
+ }
1078
+ eventNameList.forEach((eventName) => {
1079
+ (element as HTMLElement).addEventListener(eventName, stopEvent, {
1080
+ capture: Boolean(capture),
1081
+ });
1082
+ });
1083
+ }
1084
+ }
1085
+ }
1086
+
1087
+ class PopsDOMUtils extends PopsDOMUtilsEvent {
1088
+ /** 获取 animationend 在各个浏览器的兼容名 */
1089
+ getAnimationEndNameList() {
1090
+ return [
1091
+ "webkitAnimationEnd",
1092
+ "mozAnimationEnd",
1093
+ "MSAnimationEnd",
1094
+ "oanimationend",
1095
+ "animationend",
1096
+ ];
1097
+ }
1098
+ /** 获取 transitionend 在各个浏览器的兼容名 */
1099
+ getTransitionEndNameList() {
1100
+ return [
1101
+ "webkitTransitionEnd",
1102
+ "mozTransitionEnd",
1103
+ "MSTransitionEnd",
1104
+ "otransitionend",
1105
+ "transitionend",
1106
+ ];
1107
+ }
1108
+ /**
1109
+ * 实现jQuery中的$().offset();
1110
+ * @param {HTMLElement} element
1111
+ * @returns
1112
+ */
1113
+ offset(element: HTMLElement) {
1114
+ let rect = element.getBoundingClientRect();
1115
+ let win = element.ownerDocument.defaultView;
1116
+ let resultRect = new DOMRect(
1117
+ parseFloat((rect.left + (win?.pageXOffset || 0)).toString()),
1118
+ parseFloat((rect.top + (win?.pageYOffset || 0)).toString()),
1119
+ rect.width,
1120
+ rect.height
1121
+ );
1122
+ return resultRect;
1123
+ }
1124
+ /**
1125
+ * 获取元素的宽度
1126
+ * @param element 要获取宽度的元素
1127
+ * @param isShow 是否已进行isShow,避免爆堆栈
1128
+ * @returns 元素的宽度,单位为像素
1129
+ * @example
1130
+ * // 获取元素a.xx的宽度
1131
+ * DOMUtils.width(document.querySelector("a.xx"))
1132
+ * DOMUtils.width("a.xx")
1133
+ * > 100
1134
+ * // 获取window的宽度
1135
+ * DOMUtils.width(window)
1136
+ * > 400
1137
+ * @example
1138
+ * // 设置元素a.xx的宽度为200
1139
+ * DOMUtils.width(document.querySelector("a.xx"),200)
1140
+ * DOMUtils.width("a.xx",200)
1141
+ */
1142
+ width(
1143
+ element: HTMLElement | string | Window | Document | typeof globalThis,
1144
+ isShow?: boolean
1145
+ ): number;
1146
+ width(
1147
+ element: HTMLElement | string | Window | Document | typeof globalThis,
1148
+ isShow: boolean = false
1149
+ ) {
1150
+ let DOMUtilsContext = this;
1151
+ if (typeof element === "string") {
1152
+ element = PopsCore.document.querySelector(element) as HTMLElement;
1153
+ }
1154
+ if (element == null) {
1155
+ return;
1156
+ }
1157
+ if (popsUtils.isWin(element)) {
1158
+ return PopsCore.window.document.documentElement.clientWidth;
1159
+ }
1160
+ if ((element as HTMLElement).nodeType === 9) {
1161
+ /* Document文档节点 */
1162
+ element = element as Document;
1163
+ return Math.max(
1164
+ element.body.scrollWidth,
1165
+ element.documentElement.scrollWidth,
1166
+ element.body.offsetWidth,
1167
+ element.documentElement.offsetWidth,
1168
+ element.documentElement.clientWidth
1169
+ );
1170
+ }
1171
+ if (isShow || (!isShow && popsDOMUtils.isShow(element as HTMLElement))) {
1172
+ /* 已显示 */
1173
+ /* 不从style中获取对应的宽度,因为可能使用了class定义了width !important */
1174
+ element = element as HTMLElement;
1175
+ /* 如果element.style.width为空 则从css里面获取是否定义了width信息如果定义了 则读取css里面定义的宽度width */
1176
+ if (
1177
+ parseFloat(popsDOMUtils.getStyleValue(element, "width").toString()) > 0
1178
+ ) {
1179
+ return parseFloat(
1180
+ popsDOMUtils.getStyleValue(element, "width").toString()
1181
+ );
1182
+ }
1183
+
1184
+ /* 如果从css里获取到的值不是大于0 可能是auto 则通过offsetWidth来进行计算 */
1185
+ if (element.offsetWidth > 0) {
1186
+ let borderLeftWidth = popsDOMUtils.getStyleValue(
1187
+ element,
1188
+ "borderLeftWidth"
1189
+ );
1190
+ let borderRightWidth = popsDOMUtils.getStyleValue(
1191
+ element,
1192
+ "borderRightWidth"
1193
+ );
1194
+ let paddingLeft = popsDOMUtils.getStyleValue(element, "paddingLeft");
1195
+ let paddingRight = popsDOMUtils.getStyleValue(element, "paddingRight");
1196
+ let backHeight =
1197
+ parseFloat(element.offsetWidth.toString()) -
1198
+ parseFloat(borderLeftWidth.toString()) -
1199
+ parseFloat(borderRightWidth.toString()) -
1200
+ parseFloat(paddingLeft.toString()) -
1201
+ parseFloat(paddingRight.toString());
1202
+ return parseFloat(backHeight.toString());
1203
+ }
1204
+ return 0;
1205
+ } else {
1206
+ /* 未显示 */
1207
+ element = element as HTMLElement;
1208
+ let { recovery } = popsDOMUtils.showElement(element);
1209
+ let width = DOMUtilsContext.width(element, true);
1210
+ recovery();
1211
+ return width;
1212
+ }
1213
+ }
1214
+
1215
+ /**
1216
+ * 获取元素的高度
1217
+ * @param element 要获取高度的元素
1218
+ * @param isShow 是否已进行isShow,避免爆堆栈
1219
+ * @returns 元素的高度,单位为像素
1220
+ * @example
1221
+ * // 获取元素a.xx的高度
1222
+ * DOMUtils.height(document.querySelector("a.xx"))
1223
+ * DOMUtils.height("a.xx")
1224
+ * > 100
1225
+ * // 获取window的高度
1226
+ * DOMUtils.height(window)
1227
+ * > 700
1228
+ * @example
1229
+ * // 设置元素a.xx的高度为200
1230
+ * DOMUtils.height(document.querySelector("a.xx"),200)
1231
+ * DOMUtils.height("a.xx",200)
1232
+ */
1233
+ height(
1234
+ element: HTMLElement | string | Window | Document | typeof globalThis,
1235
+ isShow?: boolean
1236
+ ): number;
1237
+ height(
1238
+ element: HTMLElement | string | Window | Document | typeof globalThis,
1239
+ isShow: boolean = false
1240
+ ) {
1241
+ let DOMUtilsContext = this;
1242
+ if (popsUtils.isWin(element)) {
1243
+ return PopsCore.window.document.documentElement.clientHeight;
1244
+ }
1245
+ if (typeof element === "string") {
1246
+ element = PopsCore.document.querySelector(element) as HTMLElement;
1247
+ }
1248
+ if (element == null) {
1249
+ return;
1250
+ }
1251
+ if ((element as Document).nodeType === 9) {
1252
+ element = element as Document;
1253
+ /* Document文档节点 */
1254
+ return Math.max(
1255
+ element.body.scrollHeight,
1256
+ element.documentElement.scrollHeight,
1257
+ element.body.offsetHeight,
1258
+ element.documentElement.offsetHeight,
1259
+ element.documentElement.clientHeight
1260
+ );
1261
+ }
1262
+ if (isShow || (!isShow && popsDOMUtils.isShow(element as HTMLElement))) {
1263
+ element = element as HTMLElement;
1264
+ /* 已显示 */
1265
+ /* 从style中获取对应的高度,因为可能使用了class定义了width !important */
1266
+ /* 如果element.style.height为空 则从css里面获取是否定义了height信息如果定义了 则读取css里面定义的高度height */
1267
+ if (
1268
+ parseFloat(popsDOMUtils.getStyleValue(element, "height").toString()) > 0
1269
+ ) {
1270
+ return parseFloat(
1271
+ popsDOMUtils.getStyleValue(element, "height").toString()
1272
+ );
1273
+ }
1274
+
1275
+ /* 如果从css里获取到的值不是大于0 可能是auto 则通过offsetHeight来进行计算 */
1276
+ if (element.offsetHeight > 0) {
1277
+ let borderTopWidth = popsDOMUtils.getStyleValue(
1278
+ element,
1279
+ "borderTopWidth"
1280
+ );
1281
+ let borderBottomWidth = popsDOMUtils.getStyleValue(
1282
+ element,
1283
+ "borderBottomWidth"
1284
+ );
1285
+ let paddingTop = popsDOMUtils.getStyleValue(element, "paddingTop");
1286
+ let paddingBottom = popsDOMUtils.getStyleValue(
1287
+ element,
1288
+ "paddingBottom"
1289
+ );
1290
+ let backHeight =
1291
+ parseFloat(element.offsetHeight.toString()) -
1292
+ parseFloat(borderTopWidth.toString()) -
1293
+ parseFloat(borderBottomWidth.toString()) -
1294
+ parseFloat(paddingTop.toString()) -
1295
+ parseFloat(paddingBottom.toString());
1296
+ return parseFloat(backHeight.toString());
1297
+ }
1298
+ return 0;
1299
+ } else {
1300
+ /* 未显示 */
1301
+ element = element as HTMLElement;
1302
+ let { recovery } = popsDOMUtils.showElement(element);
1303
+ let height = DOMUtilsContext.height(element, true);
1304
+ recovery();
1305
+ return height;
1306
+ }
1307
+ }
1308
+ /**
1309
+ * 获取元素的外部宽度(包括边框和外边距)
1310
+ * @param {HTMLElement|string} element 要获取外部宽度的元素
1311
+ * @param {boolean} [isShow=false] 是否已进行isShow,避免爆堆栈
1312
+ * @returns {number} 元素的外部宽度,单位为像素
1313
+ * @example
1314
+ * // 获取元素a.xx的外部宽度
1315
+ * DOMUtils.outerWidth(document.querySelector("a.xx"))
1316
+ * DOMUtils.outerWidth("a.xx")
1317
+ * > 100
1318
+ * // 获取window的外部宽度
1319
+ * DOMUtils.outerWidth(window)
1320
+ * > 400
1321
+ */
1322
+ outerWidth(
1323
+ element: HTMLElement | string | Window | Document,
1324
+ isShow?: boolean
1325
+ ): number;
1326
+ outerWidth(
1327
+ element: HTMLElement | string | Window | Document,
1328
+ isShow: boolean = false
1329
+ ) {
1330
+ let DOMUtilsContext = this;
1331
+ if (popsUtils.isWin(element)) {
1332
+ return PopsCore.window.innerWidth;
1333
+ }
1334
+ if (typeof element === "string") {
1335
+ element = PopsCore.document.querySelector(element) as HTMLElement;
1336
+ }
1337
+ if (element == null) {
1338
+ return;
1339
+ }
1340
+ element = element as HTMLElement;
1341
+ if (isShow || (!isShow && popsDOMUtils.isShow(element))) {
1342
+ let style = getComputedStyle(element, null);
1343
+ let marginLeft = popsDOMUtils.getStyleValue(style, "marginLeft");
1344
+ let marginRight = popsDOMUtils.getStyleValue(style, "marginRight");
1345
+ return element.offsetWidth + marginLeft + marginRight;
1346
+ } else {
1347
+ let { recovery } = popsDOMUtils.showElement(element);
1348
+ let outerWidth = DOMUtilsContext.outerWidth(element, true);
1349
+ recovery();
1350
+ return outerWidth;
1351
+ }
1352
+ }
1353
+ /**
1354
+ * 获取元素的外部高度(包括边框和外边距)
1355
+ * @param {HTMLElement|string} element 要获取外部高度的元素
1356
+ * @param {boolean} [isShow=false] 是否已进行isShow,避免爆堆栈
1357
+ * @returns {number} 元素的外部高度,单位为像素
1358
+ * @example
1359
+ * // 获取元素a.xx的外部高度
1360
+ * DOMUtils.outerHeight(document.querySelector("a.xx"))
1361
+ * DOMUtils.outerHeight("a.xx")
1362
+ * > 100
1363
+ * // 获取window的外部高度
1364
+ * DOMUtils.outerHeight(window)
1365
+ * > 700
1366
+ */
1367
+ outerHeight(element: HTMLElement | string | Window, isShow?: boolean): number;
1368
+ outerHeight(
1369
+ element: HTMLElement | string | Window,
1370
+ isShow: boolean = false
1371
+ ): number {
1372
+ let DOMUtilsContext = this;
1373
+ if (popsUtils.isWin(element)) {
1374
+ return PopsCore.window.innerHeight;
1375
+ }
1376
+ if (typeof element === "string") {
1377
+ element = PopsCore.document.querySelector(element) as HTMLElement;
1378
+ }
1379
+ if (element == null) {
1380
+ // @ts-ignore
1381
+ return;
1382
+ }
1383
+ element = element as HTMLElement;
1384
+ if (isShow || (!isShow && popsDOMUtils.isShow(element))) {
1385
+ let style = getComputedStyle(element, null);
1386
+ let marginTop = popsDOMUtils.getStyleValue(style, "marginTop");
1387
+ let marginBottom = popsDOMUtils.getStyleValue(style, "marginBottom");
1388
+ return element.offsetHeight + marginTop + marginBottom;
1389
+ } else {
1390
+ let { recovery } = popsDOMUtils.showElement(element);
1391
+ let outerHeight = DOMUtilsContext.outerHeight(element, true);
1392
+ recovery();
1393
+ return outerHeight;
1394
+ }
1395
+ }
1396
+ /**
1397
+ * 添加className
1398
+ * @param element 目标元素
1399
+ * @param className className属性
1400
+ */
1401
+ addClassName(element: HTMLElement, className: string) {
1402
+ if (typeof className !== "string") {
1403
+ return;
1404
+ }
1405
+ if (className.trim() === "") {
1406
+ return;
1407
+ }
1408
+ element.classList.add(className);
1409
+ }
1410
+ /**
1411
+ * 删除className
1412
+ * @param element 目标元素
1413
+ * @param className className属性
1414
+ */
1415
+ removeClassName(element: HTMLElement, className: string) {
1416
+ if (typeof className !== "string") {
1417
+ return;
1418
+ }
1419
+ if (className.trim() === "") {
1420
+ return;
1421
+ }
1422
+ element.classList.remove(className);
1423
+ }
1424
+ /**
1425
+ * 判断元素是否包含某个className
1426
+ * @param element 目标元素
1427
+ * @param className className属性
1428
+ */
1429
+ containsClassName(element: HTMLElement, className: string): boolean {
1430
+ if (typeof className !== "string") {
1431
+ return false;
1432
+ }
1433
+ if (className.trim() === "") {
1434
+ return false;
1435
+ }
1436
+ return element.classList.contains(className);
1437
+ }
1438
+ /**
1439
+ * 获取元素的样式属性值
1440
+ * @param element 目标元素
1441
+ * @param property 样式属性名或包含多个属性名和属性值的对象
1442
+ * @example
1443
+ * // 获取元素a.xx的CSS属性display
1444
+ * DOMUtils.css(document.querySelector("a.xx"),"display");
1445
+ * DOMUtils.css("a.xx","display");
1446
+ * > "none"
1447
+ * */
1448
+ css(
1449
+ element: HTMLElement | string,
1450
+ property: keyof CSSStyleDeclaration
1451
+ ): string;
1452
+ /**
1453
+ * 获取元素的样式属性值
1454
+ * @param element 目标元素
1455
+ * @param property 样式属性名或包含多个属性名和属性值的对象
1456
+ * @example
1457
+ * // 获取元素a.xx的CSS属性display
1458
+ * DOMUtils.css(document.querySelector("a.xx"),"display");
1459
+ * DOMUtils.css("a.xx","display");
1460
+ * > "none"
1461
+ * */
1462
+ css(element: HTMLElement | string, property: string): string;
1463
+ /**
1464
+ * 设置元素的样式属性
1465
+ * @param element 目标元素
1466
+ * @param property 样式属性名或包含多个属性名和属性值的对象
1467
+ * @param value 样式属性值
1468
+ * @example
1469
+ * // 设置元素a.xx的CSS属性display为block
1470
+ * DOMUtils.css(document.querySelector("a.xx"),"display","block");
1471
+ * DOMUtils.css(document.querySelector("a.xx"),"display","block !important");
1472
+ * DOMUtils.css("a.xx","display","block");
1473
+ * DOMUtils.css("a.xx","display","block !important");
1474
+ * @example
1475
+ * // 设置元素a.xx的CSS属性top为10px
1476
+ * DOMUtils.css(document.querySelector("a.xx"),"top","10px");
1477
+ * DOMUtils.css(document.querySelector("a.xx"),"top",10);
1478
+ * */
1479
+ css(
1480
+ element: HTMLElement | string,
1481
+ property: keyof CSSStyleDeclaration & string,
1482
+ value: string | number
1483
+ ): string;
1484
+ /**
1485
+ * 设置元素的样式属性
1486
+ * @param element 目标元素
1487
+ * @param property 样式属性名或包含多个属性名和属性值的对象
1488
+ * @param value 样式属性值
1489
+ * @example
1490
+ * // 设置元素a.xx的CSS属性display为block
1491
+ * DOMUtils.css(document.querySelector("a.xx"),{ display: "block" }});
1492
+ * DOMUtils.css(document.querySelector("a.xx"),{ display: "block !important" }});
1493
+ * @example
1494
+ * // 设置元素a.xx的CSS属性top为10px
1495
+ * DOMUtils.css(document.querySelector("a.xx"),{ top: "10px" });
1496
+ * DOMUtils.css(document.querySelector("a.xx"),{ top: 10 });
1497
+ * */
1498
+ css(
1499
+ element: HTMLElement | string,
1500
+ property:
1501
+ | {
1502
+ [P in keyof CSSStyleDeclaration]?: CSSStyleDeclaration[P];
1503
+ }
1504
+ | {
1505
+ [key: string]: string | number;
1506
+ }
1507
+ ): string;
1508
+ css(
1509
+ element: HTMLElement | string,
1510
+ property:
1511
+ | keyof CSSStyleDeclaration
1512
+ | string
1513
+ | {
1514
+ [P in keyof CSSStyleDeclaration]?:
1515
+ | string
1516
+ | number
1517
+ | CSSStyleDeclaration[P];
1518
+ },
1519
+ value?: string | number
1520
+ ) {
1521
+ /**
1522
+ * 把纯数字没有px的加上
1523
+ */
1524
+ function handlePixe(propertyName: string, propertyValue: string | number) {
1525
+ let allowAddPixe = [
1526
+ "width",
1527
+ "height",
1528
+ "top",
1529
+ "left",
1530
+ "right",
1531
+ "bottom",
1532
+ "font-size",
1533
+ ];
1534
+ if (typeof propertyValue === "number") {
1535
+ propertyValue = propertyValue.toString();
1536
+ }
1537
+ if (
1538
+ typeof propertyValue === "string" &&
1539
+ allowAddPixe.includes(propertyName) &&
1540
+ propertyValue.match(/[0-9]$/gi)
1541
+ ) {
1542
+ propertyValue = propertyValue + "px";
1543
+ }
1544
+ return propertyValue;
1545
+ }
1546
+ if (typeof element === "string") {
1547
+ element = PopsCore.document.querySelector(element) as HTMLElement;
1548
+ }
1549
+ if (element == null) {
1550
+ return;
1551
+ }
1552
+ if (typeof property === "string") {
1553
+ if (value == null) {
1554
+ return getComputedStyle(element).getPropertyValue(property);
1555
+ } else {
1556
+ if (value === "string" && value.includes("!important")) {
1557
+ element.style.setProperty(property, value, "important");
1558
+ } else {
1559
+ value = handlePixe(property, value);
1560
+ element.style.setProperty(property, value);
1561
+ }
1562
+ }
1563
+ } else if (typeof property === "object") {
1564
+ for (let prop in property) {
1565
+ if (
1566
+ typeof property[prop] === "string" &&
1567
+ (property[prop] as string).includes("!important")
1568
+ ) {
1569
+ element.style.setProperty(
1570
+ prop,
1571
+ property[prop] as string,
1572
+ "important"
1573
+ );
1574
+ } else {
1575
+ property[prop] = handlePixe(prop, property[prop] as string);
1576
+ element.style.setProperty(prop, property[prop] as string);
1577
+ }
1578
+ }
1579
+ }
1580
+ }
1581
+ /**
1582
+ * 创建元素
1583
+ * @param tagName 标签名
1584
+ * @param property 属性
1585
+ * @param attributes 元素上的自定义属性
1586
+ * @example
1587
+ * // 创建一个DIV元素,且属性class为xxx
1588
+ * DOMUtils.createElement("div",undefined,{ class:"xxx" });
1589
+ * > <div class="xxx"></div>
1590
+ * @example
1591
+ * // 创建一个DIV元素
1592
+ * DOMUtils.createElement("div");
1593
+ * > <div></div>
1594
+ * @example
1595
+ * // 创建一个DIV元素
1596
+ * DOMUtils.createElement("div","测试");
1597
+ * > <div>测试</div>
1598
+ */
1599
+ createElement<K extends keyof HTMLElementTagNameMap>(
1600
+ /** 元素名 */
1601
+ tagName: K,
1602
+ /** 属性 */
1603
+ property?:
1604
+ | ({
1605
+ [P in keyof HTMLElementTagNameMap[K]]?: HTMLElementTagNameMap[K][P];
1606
+ } & {
1607
+ [key: string]: any;
1608
+ })
1609
+ | string,
1610
+ /** 自定义属性 */
1611
+ attributes?: PopsDOMUtilsCreateElementAttributesMap
1612
+ ): HTMLElementTagNameMap[K] {
1613
+ let tempElement = PopsCore.document.createElement(tagName);
1614
+ if (typeof property === "string") {
1615
+ tempElement.innerHTML = property;
1616
+ return tempElement;
1617
+ }
1618
+ if (property == null) {
1619
+ property = {};
1620
+ }
1621
+ if (attributes == null) {
1622
+ attributes = {};
1623
+ }
1624
+ Object.keys(property).forEach((key) => {
1625
+ let value = property[key];
1626
+ (tempElement as any)[key] = value;
1627
+ });
1628
+ Object.keys(attributes).forEach((key) => {
1629
+ let value = attributes[key];
1630
+ if (typeof value === "object") {
1631
+ /* object转字符串 */
1632
+ value = JSON.stringify(value);
1633
+ } else if (typeof value === "function") {
1634
+ /* function转字符串 */
1635
+ value = value.toString();
1636
+ }
1637
+ tempElement.setAttribute(key, value);
1638
+ });
1639
+ return tempElement;
1640
+ }
1641
+
1642
+ /**
1643
+ * 获取文字的位置信息
1644
+ * @param input 输入框
1645
+ * @param selectionStart 起始位置
1646
+ * @param selectionEnd 结束位置
1647
+ * @param debug 是否是调试模式
1648
+ * + true 不删除临时节点元素
1649
+ * + false 删除临时节点元素
1650
+ */
1651
+ getTextBoundingRect(
1652
+ input: HTMLInputElement,
1653
+ selectionStart: number | string,
1654
+ selectionEnd: number | string,
1655
+ debug: boolean
1656
+ ): DOMRect {
1657
+ // Basic parameter validation
1658
+ if (!input || !("value" in input)) return input;
1659
+ if (typeof selectionStart == "string")
1660
+ selectionStart = parseFloat(selectionStart);
1661
+ if (typeof selectionStart != "number" || isNaN(selectionStart)) {
1662
+ selectionStart = 0;
1663
+ }
1664
+ if (selectionStart < 0) selectionStart = 0;
1665
+ else selectionStart = Math.min(input.value.length, selectionStart);
1666
+ if (typeof selectionEnd == "string")
1667
+ selectionEnd = parseFloat(selectionEnd);
1668
+ if (
1669
+ typeof selectionEnd != "number" ||
1670
+ isNaN(selectionEnd) ||
1671
+ selectionEnd < selectionStart
1672
+ ) {
1673
+ selectionEnd = selectionStart;
1674
+ }
1675
+ if (selectionEnd < 0) selectionEnd = 0;
1676
+ else selectionEnd = Math.min(input.value.length, selectionEnd);
1677
+
1678
+ // If available (thus IE), use the createTextRange method
1679
+ if (typeof (input as any).createTextRange == "function") {
1680
+ var range = (input as any).createTextRange();
1681
+ range.collapse(true);
1682
+ range.moveStart("character", selectionStart);
1683
+ range.moveEnd("character", selectionEnd - selectionStart);
1684
+ return range.getBoundingClientRect();
1685
+ }
1686
+ // createTextRange is not supported, create a fake text range
1687
+ var offset = getInputOffset(),
1688
+ topPos = offset.top,
1689
+ leftPos = offset.left,
1690
+ width = getInputCSS("width", true),
1691
+ height = getInputCSS("height", true);
1692
+
1693
+ // Styles to simulate a node in an input field
1694
+ var cssDefaultStyles = "white-space:pre;padding:0;margin:0;",
1695
+ listOfModifiers = [
1696
+ "direction",
1697
+ "font-family",
1698
+ "font-size",
1699
+ "font-size-adjust",
1700
+ "font-variant",
1701
+ "font-weight",
1702
+ "font-style",
1703
+ "letter-spacing",
1704
+ "line-height",
1705
+ "text-align",
1706
+ "text-indent",
1707
+ "text-transform",
1708
+ "word-wrap",
1709
+ "word-spacing",
1710
+ ];
1711
+ // @ts-ignore
1712
+ topPos += getInputCSS<number>("padding-top", true);
1713
+ // @ts-ignore
1714
+ topPos += getInputCSS("border-top-width", true);
1715
+ // @ts-ignore
1716
+ leftPos += getInputCSS("padding-left", true);
1717
+ // @ts-ignore
1718
+ leftPos += getInputCSS("border-left-width", true);
1719
+ leftPos += 1; //Seems to be necessary
1720
+
1721
+ for (var i = 0; i < listOfModifiers.length; i++) {
1722
+ var property = listOfModifiers[i];
1723
+ // @ts-ignore
1724
+ cssDefaultStyles += property + ":" + getInputCSS(property) + ";";
1725
+ }
1726
+ // End of CSS variable checks
1727
+ // 不能为空,不然获取不到高度
1728
+ var text = input.value || "G",
1729
+ textLen = text.length,
1730
+ fakeClone = document.createElement("div");
1731
+ if (selectionStart > 0) appendPart(0, selectionStart);
1732
+ var fakeRange = appendPart(selectionStart, selectionEnd);
1733
+ if (textLen > selectionEnd) appendPart(selectionEnd, textLen);
1734
+
1735
+ // Styles to inherit the font styles of the element
1736
+ fakeClone.style.cssText = cssDefaultStyles;
1737
+
1738
+ // Styles to position the text node at the desired position
1739
+ fakeClone.style.position = "absolute";
1740
+ fakeClone.style.top = topPos + "px";
1741
+ fakeClone.style.left = leftPos + "px";
1742
+ fakeClone.style.width = width + "px";
1743
+ fakeClone.style.height = height + "px";
1744
+ PopsCore.document.body.appendChild(fakeClone);
1745
+ var returnValue = fakeRange.getBoundingClientRect(); //Get rect
1746
+
1747
+ if (!debug) fakeClone.parentNode!.removeChild(fakeClone); //Remove temp
1748
+ return returnValue;
1749
+
1750
+ // Local functions for readability of the previous code
1751
+ /**
1752
+ *
1753
+ * @param start
1754
+ * @param end
1755
+ */
1756
+ function appendPart(start: number, end: number): HTMLSpanElement {
1757
+ var span = document.createElement("span");
1758
+ span.style.cssText = cssDefaultStyles; //Force styles to prevent unexpected results
1759
+ span.textContent = text.substring(start, end);
1760
+ fakeClone.appendChild(span);
1761
+ return span;
1762
+ }
1763
+ // Computing offset position
1764
+ function getInputOffset() {
1765
+ var body = document.body,
1766
+ win = document.defaultView,
1767
+ docElem = document.documentElement,
1768
+ box = document.createElement("div");
1769
+ box.style.paddingLeft = box.style.width = "1px";
1770
+ body.appendChild(box);
1771
+ var isBoxModel = box.offsetWidth == 2;
1772
+ body.removeChild(box);
1773
+ // @ts-ignore
1774
+ box = input.getBoundingClientRect();
1775
+ var clientTop = docElem.clientTop || body.clientTop || 0,
1776
+ clientLeft = docElem.clientLeft || body.clientLeft || 0,
1777
+ scrollTop =
1778
+ // @ts-ignore
1779
+ win.pageYOffset ||
1780
+ (isBoxModel && docElem.scrollTop) ||
1781
+ body.scrollTop,
1782
+ scrollLeft =
1783
+ // @ts-ignore
1784
+ win.pageXOffset ||
1785
+ (isBoxModel && docElem.scrollLeft) ||
1786
+ body.scrollLeft;
1787
+ return {
1788
+ // @ts-ignore
1789
+ top: box.top + scrollTop - clientTop,
1790
+ // @ts-ignore
1791
+ left: box.left + scrollLeft - clientLeft,
1792
+ };
1793
+ }
1794
+ /**
1795
+ *
1796
+ * @param prop
1797
+ * @param isnumber
1798
+ * @returns
1799
+ */
1800
+ function getInputCSS(prop: string, isnumber: boolean) {
1801
+ var val = PopsCore.document
1802
+ .defaultView!.getComputedStyle(input, null)
1803
+ .getPropertyValue(prop);
1804
+ // @ts-ignore
1805
+ return isnumber ? parseFloat(val) : val;
1806
+ }
1807
+ }
1808
+ /**
1809
+ * 使用className来隐藏元素
1810
+ * @param ele
1811
+ * @param isImportant 是否使用!important
1812
+ */
1813
+ cssHide(ele: Element | null, isImportant = false) {
1814
+ if (ele == null) {
1815
+ return;
1816
+ }
1817
+ if (isImportant) {
1818
+ ele.classList.add("pops-hide-important");
1819
+ } else {
1820
+ ele.classList.add("pops-hide");
1821
+ }
1822
+ }
1823
+ /**
1824
+ * cssHide的反向使用
1825
+ * @param ele
1826
+ */
1827
+ cssShow(ele: Element | null) {
1828
+ if (ele == null) {
1829
+ return;
1830
+ }
1831
+ ele.classList.remove("pops-hide-important");
1832
+ ele.classList.remove("pops-hide");
1833
+ }
1834
+ /**
1835
+ * 将字符串转为Element元素
1836
+ * @param html
1837
+ * @param useParser 是否使用DOMParser来生成元素,有些时候通过DOMParser生成的元素有点问题
1838
+ * + true 使用DOMPraser来转换字符串
1839
+ * + false (默认)创建一个div,里面放入字符串,然后提取firstChild
1840
+ * @param isComplete 是否是完整的
1841
+ * + true 如果useParser为true,那么返回整个使用DOMParser转换成的Document
1842
+ * 如果useParser为false,返回一个DIV元素,DIV元素内包裹着需要转换的字符串
1843
+ * + false (默认)如果useParser为true,那么返回整个使用DOMParser转换成的Document的body
1844
+ * 如果useParser为false,返回一个DIV元素的firstChild
1845
+ * @example
1846
+ * // 将字符串转为Element元素
1847
+ * DOMUtils.parseHTML("<a href='xxxx'></a>")
1848
+ * > <a href="xxxx"></a>
1849
+ * @example
1850
+ * // 使用DOMParser将字符串转为Element元素
1851
+ * DOMUtils.parseHTML("<a href='xxxx'></a>",true)
1852
+ * > <a href="xxxx"></a>
1853
+ * @example
1854
+ * // 由于需要转换的元素是多个元素,将字符串转为完整的Element元素
1855
+ * DOMUtils.parseHTML("<a href='xxxx'></a><a href='xxxx'></a>",false, true)
1856
+ * > <div><a href="xxxx"></a><a href='xxxx'></a></div>
1857
+ * @example
1858
+ * // 由于需要转换的元素是多个元素,使用DOMParser将字符串转为完整的Element元素
1859
+ * DOMUtils.parseHTML("<a href='xxxx'></a><a href='xxxx'></a>",true, true)
1860
+ * > #document
1861
+ */
1862
+ parseHTML<T1 extends boolean, T2 extends boolean>(
1863
+ html: string,
1864
+ useParser?: T1,
1865
+ isComplete?: T2
1866
+ ): ParseHTMLReturnType<T1, T2>;
1867
+ parseHTML(html: string, useParser = false, isComplete = false) {
1868
+ function parseHTMLByDOMParser() {
1869
+ let parser = new DOMParser();
1870
+ if (isComplete) {
1871
+ return parser.parseFromString(html, "text/html");
1872
+ } else {
1873
+ return parser.parseFromString(html, "text/html").body.firstChild;
1874
+ }
1875
+ }
1876
+ function parseHTMLByCreateDom() {
1877
+ let tempDIV = PopsCore.document.createElement("div");
1878
+ tempDIV.innerHTML = html;
1879
+ if (isComplete) {
1880
+ return tempDIV;
1881
+ } else {
1882
+ return tempDIV.firstChild;
1883
+ }
1884
+ }
1885
+ if (useParser) {
1886
+ return parseHTMLByDOMParser();
1887
+ } else {
1888
+ return parseHTMLByCreateDom();
1889
+ }
1890
+ }
1891
+
1892
+ /**
1893
+ * 函数在元素内部末尾添加子元素或HTML字符串
1894
+ * @param element 目标元素
1895
+ * @param content 子元素或HTML字符串
1896
+ * @example
1897
+ * // 元素a.xx的内部末尾添加一个元素
1898
+ * DOMUtils.append(document.querySelector("a.xx"),document.querySelector("b.xx"))
1899
+ * DOMUtils.append("a.xx","'<b class="xx"></b>")
1900
+ * */
1901
+ append(
1902
+ element: Element | Node | ShadowRoot | HTMLElement | string,
1903
+ content:
1904
+ | HTMLElement
1905
+ | string
1906
+ | (HTMLElement | string | Element)[]
1907
+ | NodeList
1908
+ ) {
1909
+ if (typeof element === "string") {
1910
+ element = PopsCore.document.querySelector(element) as HTMLElement;
1911
+ }
1912
+ if (element == null) {
1913
+ return;
1914
+ }
1915
+ function elementAppendChild(ele: HTMLElement, text: HTMLElement | string) {
1916
+ if (typeof content === "string") {
1917
+ ele.insertAdjacentHTML("beforeend", text as string);
1918
+ } else {
1919
+ ele.appendChild(text as HTMLElement);
1920
+ }
1921
+ }
1922
+ if (Array.isArray(content) || content instanceof NodeList) {
1923
+ /* 数组 */
1924
+ let fragment = PopsCore.document.createDocumentFragment();
1925
+ content.forEach((ele) => {
1926
+ if (typeof ele === "string") {
1927
+ ele = this.parseHTML(ele, true, false);
1928
+ }
1929
+ fragment.appendChild(ele);
1930
+ });
1931
+ element.appendChild(fragment);
1932
+ } else {
1933
+ elementAppendChild(element as HTMLElement, content);
1934
+ }
1935
+ }
1936
+ /**
1937
+ * 把元素标签添加到head内
1938
+ */
1939
+ appendHead($ele: HTMLElement) {
1940
+ if (PopsCore.document.head) {
1941
+ PopsCore.document.head.appendChild($ele);
1942
+ } else {
1943
+ PopsCore.document.documentElement.appendChild($ele);
1944
+ }
1945
+ }
1946
+ /**
1947
+ * 把元素添加进body内
1948
+ * @param $ele
1949
+ */
1950
+ appendBody($ele: HTMLElement) {
1951
+ if (PopsCore.document.body) {
1952
+ PopsCore.document.body.appendChild($ele);
1953
+ } else {
1954
+ PopsCore.document.documentElement.appendChild($ele);
1955
+ }
1956
+ }
1957
+
1958
+ /**
1959
+ * 判断元素是否已显示或已连接
1960
+ * @param element
1961
+ */
1962
+ isShow(element: HTMLElement) {
1963
+ return Boolean(element.getClientRects().length);
1964
+ }
1965
+ /**
1966
+ * 用于显示元素并获取它的高度宽度等其它属性
1967
+ * @param element
1968
+ */
1969
+ showElement(element: HTMLElement) {
1970
+ let dupNode = element.cloneNode(true) as HTMLElement;
1971
+ dupNode.setAttribute(
1972
+ "style",
1973
+ "visibility: hidden !important;display:block !important;"
1974
+ );
1975
+ PopsCore.document.documentElement.appendChild(dupNode);
1976
+ return {
1977
+ /**
1978
+ * 恢复修改的style
1979
+ */
1980
+ recovery() {
1981
+ dupNode.remove();
1982
+ },
1983
+ };
1984
+ }
1985
+ /**
1986
+ * 获取元素上的Float格式的属性px
1987
+ * @param element
1988
+ * @param styleName style名
1989
+ */
1990
+ getStyleValue(element: HTMLElement | CSSStyleDeclaration, styleName: string) {
1991
+ let view = null;
1992
+ let styles = null;
1993
+ if (element instanceof CSSStyleDeclaration) {
1994
+ /* 直接就获取了style属性 */
1995
+ styles = element;
1996
+ } else {
1997
+ view = element.ownerDocument.defaultView;
1998
+ if (!view || !view.opener) {
1999
+ view = window;
2000
+ }
2001
+ styles = view.getComputedStyle(element);
2002
+ }
2003
+ let value = parseFloat(styles[styleName as any]);
2004
+ if (isNaN(value)) {
2005
+ return 0;
2006
+ } else {
2007
+ return value;
2008
+ }
2009
+ }
2010
+ }
2011
+
2012
+ const popsDOMUtils = new PopsDOMUtils();
2013
+ export { popsDOMUtils };