@whitesev/pops 2.2.8 → 2.3.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 (146) hide show
  1. package/dist/index.amd.js +2817 -3012
  2. package/dist/index.amd.js.map +1 -1
  3. package/dist/index.cjs.js +2817 -3012
  4. package/dist/index.cjs.js.map +1 -1
  5. package/dist/index.esm.js +2817 -3012
  6. package/dist/index.esm.js.map +1 -1
  7. package/dist/index.iife.js +2817 -3012
  8. package/dist/index.iife.js.map +1 -1
  9. package/dist/index.system.js +2817 -3012
  10. package/dist/index.system.js.map +1 -1
  11. package/dist/index.umd.js +2817 -3012
  12. package/dist/index.umd.js.map +1 -1
  13. package/dist/types/src/Pops.d.ts +497 -192
  14. package/dist/types/src/PopsIcon.d.ts +2 -2
  15. package/dist/types/src/components/panel/index.d.ts +1 -1
  16. package/dist/types/src/components/rightClickMenu/index.d.ts +487 -182
  17. package/dist/types/src/components/tooltip/index.d.ts +2 -2
  18. package/dist/types/src/types/PopsDOMUtilsEventType.d.ts +256 -259
  19. package/dist/types/src/types/animation.d.ts +19 -19
  20. package/dist/types/src/types/button.d.ts +187 -196
  21. package/dist/types/src/types/components.d.ts +213 -229
  22. package/dist/types/src/types/event.d.ts +63 -63
  23. package/dist/types/src/types/global.d.ts +20 -20
  24. package/dist/types/src/types/icon.d.ts +32 -32
  25. package/dist/types/src/types/inst.d.ts +24 -24
  26. package/dist/types/src/types/main.d.ts +114 -122
  27. package/dist/types/src/types/mask.d.ts +49 -49
  28. package/dist/types/src/types/position.d.ts +60 -60
  29. package/package.json +13 -8
  30. package/src/Pops.ts +0 -209
  31. package/src/PopsAnimation.ts +0 -32
  32. package/src/PopsCSS.ts +0 -51
  33. package/src/PopsCore.ts +0 -44
  34. package/src/PopsIcon.ts +0 -95
  35. package/src/PopsInst.ts +0 -21
  36. package/src/components/alert/config.ts +0 -62
  37. package/src/components/alert/index.css +0 -0
  38. package/src/components/alert/index.ts +0 -181
  39. package/src/components/alert/types/index.ts +0 -30
  40. package/src/components/confirm/config.ts +0 -90
  41. package/src/components/confirm/index.css +0 -0
  42. package/src/components/confirm/index.ts +0 -192
  43. package/src/components/confirm/types/index.ts +0 -17
  44. package/src/components/drawer/config.ts +0 -89
  45. package/src/components/drawer/index.css +0 -35
  46. package/src/components/drawer/index.ts +0 -260
  47. package/src/components/drawer/types/index.ts +0 -61
  48. package/src/components/folder/config.ts +0 -147
  49. package/src/components/folder/folderIcon.ts +0 -28
  50. package/src/components/folder/index.css +0 -314
  51. package/src/components/folder/index.ts +0 -1050
  52. package/src/components/folder/types/index.ts +0 -101
  53. package/src/components/iframe/config.ts +0 -60
  54. package/src/components/iframe/index.css +0 -75
  55. package/src/components/iframe/index.ts +0 -351
  56. package/src/components/iframe/types/index.ts +0 -146
  57. package/src/components/loading/config.ts +0 -29
  58. package/src/components/loading/index.css +0 -66
  59. package/src/components/loading/index.ts +0 -114
  60. package/src/components/loading/types/index.ts +0 -40
  61. package/src/components/panel/config.ts +0 -550
  62. package/src/components/panel/handlerComponents.ts +0 -3277
  63. package/src/components/panel/index.css +0 -1292
  64. package/src/components/panel/index.ts +0 -213
  65. package/src/components/panel/types/components-button.ts +0 -69
  66. package/src/components/panel/types/components-common.ts +0 -55
  67. package/src/components/panel/types/components-deepMenu.ts +0 -85
  68. package/src/components/panel/types/components-forms.ts +0 -45
  69. package/src/components/panel/types/components-input.ts +0 -82
  70. package/src/components/panel/types/components-own.ts +0 -31
  71. package/src/components/panel/types/components-select.ts +0 -101
  72. package/src/components/panel/types/components-selectMultiple.ts +0 -133
  73. package/src/components/panel/types/components-slider.ts +0 -78
  74. package/src/components/panel/types/components-switch.ts +0 -57
  75. package/src/components/panel/types/components-textarea.ts +0 -69
  76. package/src/components/panel/types/index.ts +0 -177
  77. package/src/components/prompt/config.ts +0 -94
  78. package/src/components/prompt/index.css +0 -34
  79. package/src/components/prompt/index.ts +0 -222
  80. package/src/components/prompt/types/index.ts +0 -55
  81. package/src/components/rightClickMenu/config.ts +0 -130
  82. package/src/components/rightClickMenu/index.css +0 -88
  83. package/src/components/rightClickMenu/index.ts +0 -689
  84. package/src/components/rightClickMenu/types/index.ts +0 -91
  85. package/src/components/searchSuggestion/config.ts +0 -59
  86. package/src/components/searchSuggestion/index.ts +0 -708
  87. package/src/components/searchSuggestion/types/index.ts +0 -147
  88. package/src/components/tooltip/config.ts +0 -34
  89. package/src/components/tooltip/index.css +0 -196
  90. package/src/components/tooltip/index.ts +0 -655
  91. package/src/components/tooltip/types/index.ts +0 -125
  92. package/src/config/CommonCSSClassName.ts +0 -17
  93. package/src/config/GlobalConfig.ts +0 -80
  94. package/src/css/animation.css +0 -2245
  95. package/src/css/button.css +0 -542
  96. package/src/css/common.css +0 -52
  97. package/src/css/index.css +0 -254
  98. package/src/css/ninePalaceGridPosition.css +0 -50
  99. package/src/css/scrollbar.css +0 -22
  100. package/src/handler/PopsElementHandler.ts +0 -325
  101. package/src/handler/PopsHandler.ts +0 -719
  102. package/src/svg/arrowLeft.svg +0 -4
  103. package/src/svg/arrowRight.svg +0 -4
  104. package/src/svg/chromeFilled.svg +0 -14
  105. package/src/svg/circleClose.svg +0 -8
  106. package/src/svg/close.svg +0 -5
  107. package/src/svg/cpu.svg +0 -8
  108. package/src/svg/delete.svg +0 -5
  109. package/src/svg/documentCopy.svg +0 -5
  110. package/src/svg/edit.svg +0 -8
  111. package/src/svg/eleme.svg +0 -5
  112. package/src/svg/elemePlus.svg +0 -5
  113. package/src/svg/headset.svg +0 -5
  114. package/src/svg/hide.svg +0 -8
  115. package/src/svg/keyboard.svg +0 -8
  116. package/src/svg/loading.svg +0 -5
  117. package/src/svg/max.svg +0 -5
  118. package/src/svg/min.svg +0 -5
  119. package/src/svg/mise.svg +0 -5
  120. package/src/svg/monitor.svg +0 -5
  121. package/src/svg/next.svg +0 -5
  122. package/src/svg/picture.svg +0 -8
  123. package/src/svg/prev.svg +0 -5
  124. package/src/svg/search.svg +0 -5
  125. package/src/svg/share.svg +0 -5
  126. package/src/svg/upload.svg +0 -5
  127. package/src/svg/videoPause.svg +0 -5
  128. package/src/svg/videoPlay.svg +0 -5
  129. package/src/svg/view.svg +0 -5
  130. package/src/types/PopsDOMUtilsEventType.d.ts +0 -259
  131. package/src/types/animation.d.ts +0 -19
  132. package/src/types/button.d.ts +0 -196
  133. package/src/types/components.d.ts +0 -229
  134. package/src/types/event.d.ts +0 -63
  135. package/src/types/global.d.ts +0 -20
  136. package/src/types/icon.d.ts +0 -32
  137. package/src/types/inst.d.ts +0 -24
  138. package/src/types/main.d.ts +0 -122
  139. package/src/types/mask.d.ts +0 -49
  140. package/src/types/position.d.ts +0 -60
  141. package/src/utils/PopsDOMUtils.ts +0 -2649
  142. package/src/utils/PopsDOMUtilsEventsConfig.ts +0 -6
  143. package/src/utils/PopsInstanceUtils.ts +0 -801
  144. package/src/utils/PopsMathUtils.ts +0 -77
  145. package/src/utils/PopsSafeUtils.ts +0 -24
  146. package/src/utils/PopsUtils.ts +0 -430
@@ -1,2649 +0,0 @@
1
- import type {
2
- ParseHTMLReturnType,
3
- PopsDOMUtils_EventType,
4
- PopsDOMUtilsCreateElementAttributesMap,
5
- PopsDOMUtilsEventListenerOption,
6
- PopsDOMUtilsEventListenerOptionsAttribute,
7
- PopsDOMUtils_Event,
8
- PopsDOMUtilsElementEventType,
9
- } from "../types/PopsDOMUtilsEventType";
10
- import { SymbolEvents } from "./PopsDOMUtilsEventsConfig";
11
- import { OriginPrototype, PopsCore } from "../PopsCore";
12
- import { popsUtils } from "./PopsUtils";
13
- import { PopsSafeUtils } from "./PopsSafeUtils";
14
- import { PopsCommonCSSClassName } from "../config/CommonCSSClassName";
15
-
16
- class PopsDOMUtilsEvent {
17
- /**
18
- * 绑定事件
19
- * @param element 需要绑定的元素|元素数组|window
20
- * @param eventType 需要监听的事件
21
- * @param callback 绑定事件触发的回调函数
22
- * @param option
23
- * + capture 表示事件是否在捕获阶段触发。默认为false,即在冒泡阶段触发
24
- * + once 表示事件是否只触发一次。默认为false
25
- * + passive 表示事件监听器是否不会调用preventDefault()。默认为false
26
- * @example
27
- * // 监听元素a.xx的click事件
28
- * DOMUtils.on(document.querySelector("a.xx"),"click",(event)=>{
29
- * console.log("事件触发",event)
30
- * })
31
- * DOMUtils.on("a.xx","click",(event)=>{
32
- * console.log("事件触发",event)
33
- * })
34
- */
35
- on<T extends PopsDOMUtils_EventType>(
36
- element: PopsDOMUtilsElementEventType,
37
- eventType: T | T[],
38
- callback: (this: HTMLElement, event: PopsDOMUtils_Event[T]) => void,
39
- option?: PopsDOMUtilsEventListenerOption | boolean
40
- ): void;
41
- /**
42
- * 绑定事件
43
- * @param element 需要绑定的元素|元素数组|window
44
- * @param eventType 需要监听的事件
45
- * @param callback 绑定事件触发的回调函数
46
- * @param option
47
- * + capture 表示事件是否在捕获阶段触发。默认为false,即在冒泡阶段触发
48
- * + once 表示事件是否只触发一次。默认为false
49
- * + passive 表示事件监听器是否不会调用preventDefault()。默认为false
50
- * @example
51
- * // 监听元素a.xx的click事件
52
- * DOMUtils.on(document.querySelector("a.xx"),"click",(event)=>{
53
- * console.log("事件触发",event)
54
- * })
55
- * DOMUtils.on("a.xx","click",(event)=>{
56
- * console.log("事件触发",event)
57
- * })
58
- */
59
- on<T extends Event>(
60
- element: PopsDOMUtilsElementEventType,
61
- eventType: string | string[],
62
- callback: (this: HTMLElement, event: T) => void,
63
- option?: PopsDOMUtilsEventListenerOption | boolean
64
- ): void;
65
- /**
66
- * 绑定事件
67
- * @param element 需要绑定的元素|元素数组|window
68
- * @param eventType 需要监听的事件
69
- * @param selector 子元素选择器
70
- * @param callback 绑定事件触发的回调函数
71
- * @param option
72
- * + capture 表示事件是否在捕获阶段触发。默认为false,即在冒泡阶段触发
73
- * + once 表示事件是否只触发一次。默认为false
74
- * + passive 表示事件监听器是否不会调用preventDefault()。默认为false
75
- * @example
76
- * // 监听元素a.xx的click、tap、hover事件
77
- * DOMUtils.on(document.querySelector("a.xx"),"click tap hover",(event, selectorTarget)=>{
78
- * console.log("事件触发", event, selectorTarget)
79
- * })
80
- * DOMUtils.on("a.xx",["click","tap","hover"],(event, selectorTarget)=>{
81
- * console.log("事件触发", event, selectorTarget)
82
- * })
83
- * @example
84
- * // 监听全局document下的子元素a.xx的click事件
85
- * DOMUtils.on(document,"click tap hover","a.xx",(event, selectorTarget)=>{
86
- * console.log("事件触发", event, selectorTarget)
87
- * })
88
- */
89
- on<T extends PopsDOMUtils_EventType>(
90
- element: PopsDOMUtilsElementEventType,
91
- eventType: T | T[],
92
- selector: string | string[] | undefined | null,
93
- callback: (
94
- this: HTMLElement,
95
- event: PopsDOMUtils_Event[T],
96
- selectorTarget: HTMLElement
97
- ) => void,
98
- option?: PopsDOMUtilsEventListenerOption | boolean
99
- ): void;
100
- /**
101
- * 绑定事件
102
- * @param element 需要绑定的元素|元素数组|window
103
- * @param eventType 需要监听的事件
104
- * @param selector 子元素选择器
105
- * @param callback 绑定事件触发的回调函数
106
- * @param option
107
- * + capture 表示事件是否在捕获阶段触发。默认为false,即在冒泡阶段触发
108
- * + once 表示事件是否只触发一次。默认为false
109
- * + passive 表示事件监听器是否不会调用preventDefault()。默认为false
110
- * @example
111
- * // 监听元素a.xx的click、tap、hover事件
112
- * DOMUtils.on(document.querySelector("a.xx"),"click tap hover",(event, selectorTarget)=>{
113
- * console.log("事件触发", event, selectorTarget)
114
- * })
115
- * DOMUtils.on("a.xx",["click","tap","hover"],(event, selectorTarget)=>{
116
- * console.log("事件触发", event, selectorTarget)
117
- * })
118
- * @example
119
- * // 监听全局document下的子元素a.xx的click事件
120
- * DOMUtils.on(document,"click tap hover","a.xx",(event, selectorTarget)=>{
121
- * console.log("事件触发", event, selectorTarget)
122
- * })
123
- */
124
- on<T extends Event>(
125
- element: PopsDOMUtilsElementEventType,
126
- eventType: string | string[],
127
- selector: string | string[] | undefined | null,
128
- callback: (
129
- this: HTMLElement,
130
- event: T,
131
- selectorTarget: HTMLElement
132
- ) => void,
133
- option?: PopsDOMUtilsEventListenerOption | boolean
134
- ): void;
135
- on<T extends Event>(
136
- element:
137
- | HTMLElement
138
- | string
139
- | NodeList
140
- | HTMLElement[]
141
- | Window
142
- | Document
143
- | Element
144
- | null
145
- | typeof globalThis,
146
- eventType:
147
- | PopsDOMUtils_EventType
148
- | PopsDOMUtils_EventType[]
149
- | string
150
- | string[],
151
- selector:
152
- | string
153
- | string[]
154
- | undefined
155
- | ((this: HTMLElement, event: T, selectorTarget: HTMLElement) => void)
156
- | null,
157
- callback?:
158
- | ((this: HTMLElement, event: T, selectorTarget: HTMLElement) => void)
159
- | PopsDOMUtilsEventListenerOption
160
- | boolean,
161
- option?: PopsDOMUtilsEventListenerOption | boolean
162
- ) {
163
- /**
164
- * 获取option配置
165
- * @param args
166
- * @param startIndex
167
- * @param option
168
- */
169
- function getOption(
170
- args: IArguments,
171
- startIndex: number,
172
- option: PopsDOMUtilsEventListenerOption
173
- ) {
174
- let currentParam = args[startIndex];
175
- if (typeof currentParam === "boolean") {
176
- option.capture = currentParam;
177
- if (typeof args[startIndex + 1] === "boolean") {
178
- option.once = args[startIndex + 1];
179
- }
180
- if (typeof args[startIndex + 2] === "boolean") {
181
- option.passive = args[startIndex + 2];
182
- }
183
- } else if (
184
- typeof currentParam === "object" &&
185
- ("capture" in currentParam ||
186
- "once" in currentParam ||
187
- "passive" in currentParam ||
188
- "isComposedPath" in currentParam)
189
- ) {
190
- option.capture = currentParam.capture;
191
- option.once = currentParam.once;
192
- option.passive = currentParam.passive;
193
- option.isComposedPath = currentParam.isComposedPath;
194
- }
195
- return option;
196
- }
197
-
198
- let DOMUtilsContext = this;
199
- let args = arguments;
200
- if (typeof element === "string") {
201
- element = DOMUtilsContext.selectorAll(element);
202
- }
203
- if (element == null) {
204
- return;
205
- }
206
- let elementList: HTMLElement[] = [];
207
- if (element instanceof NodeList || Array.isArray(element)) {
208
- element = element as HTMLElement[];
209
- elementList = [...element];
210
- } else {
211
- elementList.push(element as HTMLElement);
212
- }
213
- // 事件名
214
- let eventTypeList: string[] = [];
215
- if (Array.isArray(eventType)) {
216
- eventTypeList = eventTypeList.concat(
217
- eventType.filter(
218
- (eventTypeItem) =>
219
- typeof eventTypeItem === "string" && eventTypeItem.toString() !== ""
220
- )
221
- );
222
- } else if (typeof eventType === "string") {
223
- eventTypeList = eventTypeList.concat(
224
- eventType.split(" ").filter((eventTypeItem) => eventTypeItem !== "")
225
- );
226
- }
227
- // 子元素选择器
228
- let selectorList: string[] = [];
229
- if (Array.isArray(selector)) {
230
- selectorList = selectorList.concat(
231
- selector.filter(
232
- (selectorItem) =>
233
- typeof selectorItem === "string" && selectorItem.toString() !== ""
234
- )
235
- );
236
- } else if (typeof selector === "string") {
237
- selectorList.push(selector);
238
- }
239
- // 事件回调
240
- let listenerCallBack: (
241
- this: HTMLElement,
242
- event: Event,
243
- selectorTarget?: HTMLElement
244
- ) => void = callback as any;
245
- // 事件配置
246
- let listenerOption: PopsDOMUtilsEventListenerOption = {
247
- capture: false,
248
- once: false,
249
- passive: false,
250
- isComposedPath: false,
251
- };
252
- if (typeof selector === "function") {
253
- // 这是为没有selector的情况
254
- // 那么它就是callback
255
- listenerCallBack = selector as any;
256
- listenerOption = getOption(args, 3, listenerOption);
257
- } else {
258
- // 这是存在selector的情况
259
- listenerOption = getOption(args, 4, listenerOption);
260
- }
261
- /**
262
- * 如果是once,那么删除该监听和元素上的事件和监听
263
- */
264
- function checkOptionOnceToRemoveEventListener() {
265
- if (listenerOption.once) {
266
- DOMUtilsContext.off(
267
- element,
268
- eventType as any,
269
- selector as any,
270
- callback as any,
271
- option
272
- );
273
- }
274
- }
275
- elementList.forEach((elementItem) => {
276
- /**
277
- * 事件回调
278
- * @param event
279
- */
280
- function domUtilsEventCallBack(event: Event) {
281
- if (selectorList.length) {
282
- /* 存在子元素选择器 */
283
- // 这时候的this和target都是子元素选择器的元素
284
- let eventTarget = listenerOption.isComposedPath
285
- ? (event.composedPath()[0] as HTMLElement)
286
- : (event.target as HTMLElement);
287
- let totalParent = elementItem;
288
- if (popsUtils.isWin(totalParent)) {
289
- if (totalParent === (PopsCore.document as any as HTMLElement)) {
290
- totalParent = PopsCore.document.documentElement;
291
- }
292
- }
293
- let findValue = selectorList.find((selectorItem) => {
294
- // 判断目标元素是否匹配选择器
295
- if (DOMUtilsContext.matches(eventTarget, selectorItem)) {
296
- /* 当前目标可以被selector所匹配到 */
297
- return true;
298
- }
299
- /* 在上层与主元素之间寻找可以被selector所匹配到的 */
300
- let $closestMatches = DOMUtilsContext.closest<HTMLElement>(
301
- eventTarget,
302
- selectorItem
303
- );
304
- if ($closestMatches && totalParent?.contains($closestMatches)) {
305
- eventTarget = $closestMatches;
306
- return true;
307
- }
308
- return false;
309
- });
310
- if (findValue) {
311
- // 这里尝试使用defineProperty修改event的target值
312
- try {
313
- OriginPrototype.Object.defineProperty(event, "target", {
314
- get() {
315
- return eventTarget;
316
- },
317
- });
318
- } catch (error) {}
319
- listenerCallBack.call(eventTarget, event as any, eventTarget);
320
- checkOptionOnceToRemoveEventListener();
321
- }
322
- } else {
323
- // 这时候的this指向监听的元素
324
- listenerCallBack.call(elementItem, event as any);
325
- checkOptionOnceToRemoveEventListener();
326
- }
327
- }
328
-
329
- /* 遍历事件名设置元素事件 */
330
- eventTypeList.forEach((eventName) => {
331
- elementItem.addEventListener(
332
- eventName,
333
- domUtilsEventCallBack,
334
- listenerOption
335
- );
336
- /* 获取对象上的事件 */
337
- let elementEvents: {
338
- [k: string]: PopsDOMUtilsEventListenerOptionsAttribute[];
339
- } = Reflect.get(elementItem, SymbolEvents) || {};
340
- /* 初始化对象上的xx事件 */
341
- elementEvents[eventName] = elementEvents[eventName] || [];
342
- elementEvents[eventName].push({
343
- selector: selectorList,
344
- option: listenerOption,
345
- callback: domUtilsEventCallBack,
346
- originCallBack: listenerCallBack,
347
- });
348
- /* 覆盖事件 */
349
- Reflect.set(elementItem, SymbolEvents, elementEvents);
350
- });
351
- });
352
- }
353
- /**
354
- * 取消绑定事件
355
- * @param element 需要取消绑定的元素|元素数组
356
- * @param eventType 需要取消监听的事件
357
- * @param callback 通过DOMUtils.on绑定的事件函数
358
- * @param option
359
- * + capture 如果在添加事件监听器时指定了useCapture为true,则在移除事件监听器时也必须指定为true
360
- * @param filter (可选)过滤函数,对元素属性上的事件进行过滤出想要删除的事件
361
- * @example
362
- * // 取消监听元素a.xx所有的click事件
363
- * DOMUtils.off(document.querySelector("a.xx"),"click")
364
- * DOMUtils.off("a.xx","click")
365
- */
366
- off<T extends PopsDOMUtils_EventType>(
367
- element: PopsDOMUtilsElementEventType,
368
- eventType: T | T[],
369
- callback?: (this: HTMLElement, event: PopsDOMUtils_Event[T]) => void,
370
- option?: EventListenerOptions | boolean,
371
- filter?: (
372
- value: PopsDOMUtilsEventListenerOptionsAttribute,
373
- index: number,
374
- array: PopsDOMUtilsEventListenerOptionsAttribute[]
375
- ) => boolean
376
- ): void;
377
- /**
378
- * 取消绑定事件
379
- * @param element 需要取消绑定的元素|元素数组
380
- * @param eventType 需要取消监听的事件
381
- * @param callback 通过DOMUtils.on绑定的事件函数
382
- * @param option
383
- * + capture 如果在添加事件监听器时指定了useCapture为true,则在移除事件监听器时也必须指定为true
384
- * @param filter (可选)过滤函数,对元素属性上的事件进行过滤出想要删除的事件
385
- * @example
386
- * // 取消监听元素a.xx的click事件
387
- * DOMUtils.off(document.querySelector("a.xx"),"click")
388
- * DOMUtils.off("a.xx","click")
389
- */
390
- off<T extends Event>(
391
- element: PopsDOMUtilsElementEventType,
392
- eventType: string | string[],
393
- callback?: (this: HTMLElement, event: T) => void,
394
- option?: EventListenerOptions | boolean,
395
- filter?: (
396
- value: PopsDOMUtilsEventListenerOptionsAttribute,
397
- index: number,
398
- array: PopsDOMUtilsEventListenerOptionsAttribute[]
399
- ) => boolean
400
- ): void;
401
- /**
402
- * 取消绑定事件
403
- * @param element 需要取消绑定的元素|元素数组
404
- * @param eventType 需要取消监听的事件
405
- * @param selector 子元素选择器
406
- * @param callback 通过DOMUtils.on绑定的事件函数
407
- * @param option
408
- * + capture 如果在添加事件监听器时指定了useCapture为true,则在移除事件监听器时也必须指定为true
409
- * @param filter (可选)过滤函数,对元素属性上的事件进行过滤出想要删除的事件
410
- * @example
411
- * // 取消监听元素a.xx的click、tap、hover事件
412
- * DOMUtils.off(document.querySelector("a.xx"),"click tap hover")
413
- * DOMUtils.off("a.xx",["click","tap","hover"])
414
- */
415
- off<T extends PopsDOMUtils_EventType>(
416
- element: PopsDOMUtilsElementEventType,
417
- eventType: T | T[],
418
- selector?: string | string[] | undefined | null,
419
- callback?: (
420
- this: HTMLElement,
421
- event: PopsDOMUtils_Event[T],
422
- selectorTarget: HTMLElement
423
- ) => void,
424
- option?: EventListenerOptions | boolean,
425
- filter?: (
426
- value: PopsDOMUtilsEventListenerOptionsAttribute,
427
- index: number,
428
- array: PopsDOMUtilsEventListenerOptionsAttribute[]
429
- ) => boolean
430
- ): void;
431
- /**
432
- * 取消绑定事件
433
- * @param element 需要取消绑定的元素|元素数组
434
- * @param eventType 需要取消监听的事件
435
- * @param selector 子元素选择器
436
- * @param callback 通过DOMUtils.on绑定的事件函数
437
- * @param option
438
- * + capture 如果在添加事件监听器时指定了useCapture为true,则在移除事件监听器时也必须指定为true
439
- * @param filter (可选)过滤函数,对元素属性上的事件进行过滤出想要删除的事件
440
- * @example
441
- * // 取消监听元素a.xx的click、tap、hover事件
442
- * DOMUtils.off(document.querySelector("a.xx"),"click tap hover")
443
- * DOMUtils.off("a.xx",["click","tap","hover"])
444
- */
445
- off<T extends Event>(
446
- element: PopsDOMUtilsElementEventType,
447
- eventType: string | string[],
448
- selector?: string | string[] | undefined | null,
449
- callback?: (
450
- this: HTMLElement,
451
- event: T,
452
- selectorTarget: HTMLElement
453
- ) => void,
454
- option?: EventListenerOptions | boolean,
455
- filter?: (
456
- value: PopsDOMUtilsEventListenerOptionsAttribute,
457
- index: number,
458
- array: PopsDOMUtilsEventListenerOptionsAttribute[]
459
- ) => boolean
460
- ): void;
461
- off<T extends Event>(
462
- element:
463
- | HTMLElement
464
- | string
465
- | NodeList
466
- | HTMLElement[]
467
- | Window
468
- | Document
469
- | Element
470
- | null
471
- | typeof globalThis,
472
- eventType:
473
- | PopsDOMUtils_EventType
474
- | PopsDOMUtils_EventType[]
475
- | string
476
- | string[],
477
- selector:
478
- | string
479
- | string[]
480
- | undefined
481
- | ((this: HTMLElement, event: T, selectorTarget: HTMLElement) => void)
482
- | null,
483
- callback?:
484
- | ((this: HTMLElement, event: T, selectorTarget: HTMLElement) => void)
485
- | EventListenerOptions
486
- | boolean,
487
- option?:
488
- | EventListenerOptions
489
- | boolean
490
- | ((
491
- value: PopsDOMUtilsEventListenerOptionsAttribute,
492
- index: number,
493
- array: PopsDOMUtilsEventListenerOptionsAttribute[]
494
- ) => boolean),
495
- filter?: (
496
- value: PopsDOMUtilsEventListenerOptionsAttribute,
497
- index: number,
498
- array: PopsDOMUtilsEventListenerOptionsAttribute[]
499
- ) => boolean
500
- ) {
501
- /**
502
- * 获取option配置
503
- * @param args1
504
- * @param startIndex
505
- * @param option
506
- */
507
- function getOption(
508
- args1: IArguments,
509
- startIndex: number,
510
- option: EventListenerOptions
511
- ) {
512
- let currentParam: EventListenerOptions | boolean = args1[startIndex];
513
- if (typeof currentParam === "boolean") {
514
- option.capture = currentParam;
515
- } else if (
516
- typeof currentParam === "object" &&
517
- "capture" in currentParam
518
- ) {
519
- option.capture = currentParam.capture;
520
- }
521
- return option;
522
- }
523
- let DOMUtilsContext = this;
524
- let args = arguments;
525
- if (typeof element === "string") {
526
- element = DOMUtilsContext.selectorAll(element);
527
- }
528
- if (element == null) {
529
- return;
530
- }
531
- let elementList: HTMLElement[] = [];
532
- if (element instanceof NodeList || Array.isArray(element)) {
533
- element = element as HTMLElement[];
534
- elementList = [...element];
535
- } else {
536
- elementList.push(element as HTMLElement);
537
- }
538
- let eventTypeList: string[] = [];
539
- if (Array.isArray(eventType)) {
540
- eventTypeList = eventTypeList.concat(
541
- eventType.filter(
542
- (eventTypeItem) =>
543
- typeof eventTypeItem === "string" && eventTypeItem.toString() !== ""
544
- )
545
- );
546
- } else if (typeof eventType === "string") {
547
- eventTypeList = eventTypeList.concat(
548
- eventType.split(" ").filter((eventTypeItem) => eventTypeItem !== "")
549
- );
550
- }
551
- // 子元素选择器
552
- let selectorList: string[] = [];
553
- if (Array.isArray(selector)) {
554
- selectorList = selectorList.concat(
555
- selector.filter(
556
- (selectorItem) =>
557
- typeof selectorItem === "string" && selectorItem.toString() !== ""
558
- )
559
- );
560
- } else if (typeof selector === "string") {
561
- selectorList.push(selector);
562
- }
563
- /**
564
- * 事件的回调函数
565
- */
566
- let listenerCallBack: (
567
- this: HTMLElement,
568
- event: T,
569
- selectorTarget: HTMLElement
570
- ) => void = callback as any;
571
-
572
- /**
573
- * 事件的配置
574
- */
575
- let listenerOption: EventListenerOptions = {
576
- capture: false,
577
- };
578
- if (typeof selector === "function") {
579
- // 这是为没有selector的情况
580
- // 那么它就是callback
581
- listenerCallBack = selector;
582
- listenerOption = getOption(args, 3, listenerOption);
583
- } else {
584
- // 这是存在selector的情况
585
- listenerOption = getOption(args, 4, listenerOption);
586
- }
587
- // 是否移除所有事件
588
- let isRemoveAll = false;
589
- if (args.length === 2) {
590
- // 目标函数、事件名
591
- isRemoveAll = true;
592
- } else if (
593
- (args.length === 3 && typeof args[2] === "string") ||
594
- Array.isArray(args[2])
595
- ) {
596
- // 目标函数、事件名、子元素选择器
597
- isRemoveAll = true;
598
- }
599
- elementList.forEach((elementItem) => {
600
- /* 获取对象上的事件 */
601
- let elementEvents: {
602
- [key: string]: PopsDOMUtilsEventListenerOptionsAttribute[];
603
- } = Reflect.get(elementItem, SymbolEvents) || {};
604
- eventTypeList.forEach((eventName) => {
605
- let handlers = elementEvents[eventName] || [];
606
- if (typeof filter === "function") {
607
- handlers = handlers.filter(filter);
608
- }
609
- for (let index = 0; index < handlers.length; index++) {
610
- let handler = handlers[index];
611
- let flag = true;
612
- if (
613
- flag &&
614
- listenerCallBack &&
615
- handler.originCallBack !== listenerCallBack
616
- ) {
617
- // callback不同
618
- flag = false;
619
- }
620
- if (flag && selectorList.length && Array.isArray(handler.selector)) {
621
- if (
622
- JSON.stringify(handler.selector) !== JSON.stringify(selectorList)
623
- ) {
624
- // 子元素选择器不同
625
- flag = false;
626
- }
627
- }
628
- if (flag && listenerOption.capture !== handler.option.capture) {
629
- // 事件的配置项不同
630
- flag = false;
631
- }
632
- if (flag || isRemoveAll) {
633
- elementItem.removeEventListener(
634
- eventName,
635
- handler.callback,
636
- handler.option
637
- );
638
- handlers.splice(index--, 1);
639
- }
640
- }
641
- if (handlers.length === 0) {
642
- /* 如果没有任意的handler,那么删除该属性 */
643
- popsUtils.delete(elementEvents, eventType);
644
- }
645
- });
646
- Reflect.set(elementItem, SymbolEvents, elementEvents);
647
- });
648
- }
649
- /**
650
- * 取消绑定所有的事件
651
- * @param element 需要取消绑定的元素|元素数组
652
- * @param eventType (可选)需要取消监听的事件
653
- */
654
- offAll(element: PopsDOMUtilsElementEventType, eventType?: string): void;
655
- /**
656
- * 取消绑定所有的事件
657
- * @param element 需要取消绑定的元素|元素数组
658
- * @param eventType (可选)需要取消监听的事件
659
- */
660
- offAll(
661
- element: PopsDOMUtilsElementEventType,
662
- eventType?: PopsDOMUtils_EventType | PopsDOMUtils_EventType[]
663
- ): void;
664
- /**
665
- * 取消绑定所有的事件
666
- * @param element 需要取消绑定的元素|元素数组
667
- * @param eventType (可选)需要取消监听的事件
668
- */
669
- offAll(
670
- element: PopsDOMUtilsElementEventType,
671
- eventType?: PopsDOMUtils_EventType | PopsDOMUtils_EventType[] | string
672
- ) {
673
- if (typeof element === "string") {
674
- element = PopsCore.document.querySelectorAll(element);
675
- }
676
- if (element == null) {
677
- return;
678
- }
679
- let elementList: HTMLElement[] = [];
680
- if (element instanceof NodeList || Array.isArray(element)) {
681
- elementList = [...(element as HTMLElement[])];
682
- } else {
683
- elementList.push(element as HTMLElement);
684
- }
685
-
686
- let eventTypeList: string[] = [];
687
- if (Array.isArray(eventType)) {
688
- eventTypeList = eventTypeList.concat(eventType as string[]);
689
- } else if (typeof eventType === "string") {
690
- eventTypeList = eventTypeList.concat(eventType.split(" "));
691
- }
692
- elementList.forEach((elementItem) => {
693
- Object.getOwnPropertySymbols(elementItem).forEach((__symbolEvents) => {
694
- if (!__symbolEvents.toString().startsWith("Symbol(events_")) {
695
- return;
696
- }
697
- let elementEvents = (elementItem as any)[__symbolEvents] || {};
698
- let iterEventNameList = eventTypeList.length
699
- ? eventTypeList
700
- : Object.keys(elementEvents);
701
- iterEventNameList.forEach((eventName) => {
702
- let handlers = elementEvents[eventName];
703
- if (!handlers) {
704
- return;
705
- }
706
- for (const handler of handlers) {
707
- elementItem.removeEventListener(eventName, handler.callback, {
708
- capture: handler["option"]["capture"],
709
- });
710
- }
711
- popsUtils.delete((elementItem as any)[__symbolEvents], eventName);
712
- });
713
- });
714
- });
715
- }
716
-
717
- /**
718
- * 等待文档加载完成后执行指定的函数
719
- * @param callback 需要执行的函数
720
- * @example
721
- * DOMUtils.ready(function(){
722
- * console.log("文档加载完毕")
723
- * })
724
- */
725
- ready<T extends Function>(callback: T) {
726
- if (typeof callback !== "function") {
727
- return;
728
- }
729
- /**
730
- * 检测文档是否加载完毕
731
- */
732
- function checkDOMReadyState() {
733
- try {
734
- if (
735
- document.readyState === "complete" ||
736
- (document.readyState !== "loading" &&
737
- !(document.documentElement as any).doScroll)
738
- ) {
739
- return true;
740
- } else {
741
- return false;
742
- }
743
- } catch (error) {
744
- return false;
745
- }
746
- }
747
- /**
748
- * 成功加载完毕后触发的回调函数
749
- */
750
- function completed() {
751
- removeDomReadyListener();
752
- callback();
753
- }
754
-
755
- let targetList = [
756
- {
757
- target: PopsCore.document,
758
- eventType: "DOMContentLoaded",
759
- callback: completed,
760
- },
761
- {
762
- target: PopsCore.window,
763
- eventType: "load",
764
- callback: completed,
765
- },
766
- ];
767
- /**
768
- * 添加监听
769
- */
770
- function addDomReadyListener() {
771
- for (let index = 0; index < targetList.length; index++) {
772
- let item = targetList[index];
773
- item.target.addEventListener(item.eventType, item.callback);
774
- }
775
- }
776
- /**
777
- * 移除监听
778
- */
779
- function removeDomReadyListener() {
780
- for (let index = 0; index < targetList.length; index++) {
781
- let item = targetList[index];
782
- item.target.removeEventListener(item.eventType, item.callback);
783
- }
784
- }
785
- if (checkDOMReadyState()) {
786
- /* 检查document状态 */
787
- popsUtils.setTimeout(callback, 0);
788
- } else {
789
- /* 添加监听 */
790
- addDomReadyListener();
791
- }
792
- }
793
- /**
794
- * 主动触发事件
795
- * @param element 需要触发的元素|元素数组|window
796
- * @param eventType 需要触发的事件
797
- * @param details 赋予触发的Event的额外属性,如果是Event类型,那么将自动代替默认new的Event对象
798
- * @param useDispatchToTriggerEvent 是否使用dispatchEvent来触发事件,默认true
799
- * @example
800
- * // 触发元素a.xx的click事件
801
- * DOMUtils.trigger(document.querySelector("a.xx"),"click")
802
- * DOMUtils.trigger("a.xx","click")
803
- * // 触发元素a.xx的click、tap、hover事件
804
- * DOMUtils.trigger(document.querySelector("a.xx"),"click tap hover")
805
- * DOMUtils.trigger("a.xx",["click","tap","hover"])
806
- */
807
- trigger(
808
- element: HTMLElement | string | NodeList | any[] | Window | Document,
809
- eventType: string | string[],
810
- details?: object,
811
- useDispatchToTriggerEvent?: boolean
812
- ): void;
813
- /**
814
- * 主动触发事件
815
- * @param element 需要触发的元素|元素数组|window
816
- * @param eventType 需要触发的事件
817
- * @param details 赋予触发的Event的额外属性,如果是Event类型,那么将自动代替默认new的Event对象
818
- * @param useDispatchToTriggerEvent 是否使用dispatchEvent来触发事件,默认true
819
- * @example
820
- * // 触发元素a.xx的click事件
821
- * DOMUtils.trigger(document.querySelector("a.xx"),"click")
822
- * DOMUtils.trigger("a.xx","click")
823
- * // 触发元素a.xx的click、tap、hover事件
824
- * DOMUtils.trigger(document.querySelector("a.xx"),"click tap hover")
825
- * DOMUtils.trigger("a.xx",["click","tap","hover"])
826
- */
827
- trigger(
828
- element: HTMLElement | string | NodeList | any[] | Window | Document,
829
- eventType: PopsDOMUtils_EventType | PopsDOMUtils_EventType[],
830
- details?: object,
831
- useDispatchToTriggerEvent?: boolean
832
- ): void;
833
- /**
834
- * 主动触发事件
835
- * @param element 需要触发的元素|元素数组|window
836
- * @param eventType 需要触发的事件
837
- * @param details 赋予触发的Event的额外属性,如果是Event类型,那么将自动代替默认new的Event对象
838
- * @param useDispatchToTriggerEvent 是否使用dispatchEvent来触发事件,默认true
839
- * @example
840
- * // 触发元素a.xx的click事件
841
- * DOMUtils.trigger(document.querySelector("a.xx"),"click")
842
- * DOMUtils.trigger("a.xx","click")
843
- * // 触发元素a.xx的click、tap、hover事件
844
- * DOMUtils.trigger(document.querySelector("a.xx"),"click tap hover")
845
- * DOMUtils.trigger("a.xx",["click","tap","hover"])
846
- */
847
- trigger(
848
- element: HTMLElement | string | NodeList | any[] | Window | Document,
849
- eventType: PopsDOMUtils_EventType | PopsDOMUtils_EventType[] | string,
850
- details?: object,
851
- useDispatchToTriggerEvent: boolean = true
852
- ) {
853
- if (typeof element === "string") {
854
- element = PopsCore.document.querySelector(element) as HTMLElement;
855
- }
856
- if (element == null) {
857
- return;
858
- }
859
- let elementList = [];
860
- if (element instanceof NodeList || Array.isArray(element)) {
861
- element = element as HTMLElement[];
862
- elementList = [...element];
863
- } else {
864
- elementList = [element];
865
- }
866
- let eventTypeList: string[] = [];
867
- if (Array.isArray(eventType)) {
868
- eventTypeList = eventType as string[];
869
- } else if (typeof eventType === "string") {
870
- eventTypeList = eventType.split(" ");
871
- }
872
-
873
- elementList.forEach((elementItem) => {
874
- /* 获取对象上的事件 */
875
- let events = elementItem[SymbolEvents] || {};
876
- eventTypeList.forEach((_eventType_) => {
877
- let event: Event = null as any;
878
- if (details && details instanceof Event) {
879
- event = details;
880
- } else {
881
- event = new Event(_eventType_);
882
- if (details) {
883
- Object.keys(details).forEach((keyName) => {
884
- (event as any)[keyName] = (details as any)[keyName];
885
- });
886
- }
887
- }
888
- if (useDispatchToTriggerEvent == false && _eventType_ in events) {
889
- events[_eventType_].forEach((eventsItem: any) => {
890
- eventsItem.callback(event);
891
- });
892
- } else {
893
- elementItem.dispatchEvent(event);
894
- }
895
- });
896
- });
897
- }
898
-
899
- /**
900
- * 绑定或触发元素的click事件
901
- * @param element 目标元素
902
- * @param handler (可选)事件处理函数
903
- * @param details (可选)赋予触发的Event的额外属性
904
- * @param useDispatchToTriggerEvent (可选)是否使用dispatchEvent来触发事件,默认true
905
- * @example
906
- * // 触发元素a.xx的click事件
907
- * DOMUtils.click(document.querySelector("a.xx"))
908
- * DOMUtils.click("a.xx")
909
- * DOMUtils.click("a.xx",function(){
910
- * console.log("触发click事件成功")
911
- * })
912
- * */
913
- click(
914
- element: HTMLElement | string | Window,
915
- handler?: (event: PopsDOMUtils_Event["click"]) => void,
916
- details?: any,
917
- useDispatchToTriggerEvent?: boolean
918
- ) {
919
- let DOMUtilsContext = this;
920
- if (typeof element === "string") {
921
- element = PopsCore.document.querySelector(element) as HTMLElement;
922
- }
923
- if (element == null) {
924
- return;
925
- }
926
- if (handler == null) {
927
- DOMUtilsContext.trigger(
928
- element,
929
- "click",
930
- details,
931
- useDispatchToTriggerEvent
932
- );
933
- } else {
934
- DOMUtilsContext.on(element, "click", null, handler);
935
- }
936
- }
937
- /**
938
- * 绑定或触发元素的blur事件
939
- * @param element 目标元素
940
- * @param handler (可选)事件处理函数
941
- * @param details (可选)赋予触发的Event的额外属性
942
- * @param useDispatchToTriggerEvent (可选)是否使用dispatchEvent来触发事件,默认true
943
- * @example
944
- * // 触发元素a.xx的blur事件
945
- * DOMUtils.blur(document.querySelector("a.xx"))
946
- * DOMUtils.blur("a.xx")
947
- * DOMUtils.blur("a.xx",function(){
948
- * console.log("触发blur事件成功")
949
- * })
950
- * */
951
- blur(
952
- element: HTMLElement | string | Window,
953
- handler?: (event: PopsDOMUtils_Event["blur"]) => void,
954
- details?: object,
955
- useDispatchToTriggerEvent?: boolean
956
- ) {
957
- let DOMUtilsContext = this;
958
- if (typeof element === "string") {
959
- element = PopsCore.document.querySelector(element) as HTMLElement;
960
- }
961
- if (element == null) {
962
- return;
963
- }
964
- if (handler === null) {
965
- DOMUtilsContext.trigger(
966
- element,
967
- "blur",
968
- details,
969
- useDispatchToTriggerEvent
970
- );
971
- } else {
972
- DOMUtilsContext.on(
973
- element,
974
- "blur",
975
- null,
976
- handler as (event: Event) => void
977
- );
978
- }
979
- }
980
- /**
981
- * 绑定或触发元素的focus事件
982
- * @param element 目标元素
983
- * @param handler (可选)事件处理函数
984
- * @param details (可选)赋予触发的Event的额外属性
985
- * @param useDispatchToTriggerEvent (可选)是否使用dispatchEvent来触发事件,默认true
986
- * @example
987
- * // 触发元素a.xx的focus事件
988
- * DOMUtils.focus(document.querySelector("a.xx"))
989
- * DOMUtils.focus("a.xx")
990
- * DOMUtils.focus("a.xx",function(){
991
- * console.log("触发focus事件成功")
992
- * })
993
- * */
994
- focus(
995
- element: HTMLElement | string | Window,
996
- handler?: (event: PopsDOMUtils_Event["focus"]) => void,
997
- details?: object,
998
- useDispatchToTriggerEvent?: boolean
999
- ) {
1000
- let DOMUtilsContext = this;
1001
- if (typeof element === "string") {
1002
- element = PopsCore.document.querySelector(element) as HTMLElement;
1003
- }
1004
- if (element == null) {
1005
- return;
1006
- }
1007
- if (handler == null) {
1008
- DOMUtilsContext.trigger(
1009
- element,
1010
- "focus",
1011
- details,
1012
- useDispatchToTriggerEvent
1013
- );
1014
- } else {
1015
- DOMUtilsContext.on(element, "focus", null, handler);
1016
- }
1017
- }
1018
- /**
1019
- * 当鼠标移入或移出元素时触发事件
1020
- * @param element 当前元素
1021
- * @param handler 事件处理函数
1022
- * @param option 配置
1023
- * @example
1024
- * // 监听a.xx元素的移入或移出
1025
- * DOMUtils.hover(document.querySelector("a.xx"),()=>{
1026
- * console.log("移入/移除");
1027
- * })
1028
- * DOMUtils.hover("a.xx",()=>{
1029
- * console.log("移入/移除");
1030
- * })
1031
- */
1032
- hover(
1033
- element: HTMLElement | string,
1034
- handler: (event: PopsDOMUtils_Event["hover"]) => void,
1035
- option?: boolean | AddEventListenerOptions
1036
- ) {
1037
- let DOMUtilsContext = this;
1038
- if (typeof element === "string") {
1039
- element = PopsCore.document.querySelector(element) as HTMLElement;
1040
- }
1041
- if (element == null) {
1042
- return;
1043
- }
1044
- DOMUtilsContext.on(element, "mouseenter", null, handler, option);
1045
- DOMUtilsContext.on(element, "mouseleave", null, handler, option);
1046
- }
1047
- /**
1048
- * 当按键松开时触发事件
1049
- * keydown - > keypress - > keyup
1050
- * @param target 当前元素
1051
- * @param handler 事件处理函数
1052
- * @param option 配置
1053
- * @example
1054
- * // 监听a.xx元素的按键松开
1055
- * DOMUtils.keyup(document.querySelector("a.xx"),()=>{
1056
- * console.log("按键松开");
1057
- * })
1058
- * DOMUtils.keyup("a.xx",()=>{
1059
- * console.log("按键松开");
1060
- * })
1061
- */
1062
- keyup(
1063
- target: HTMLElement | string | Window | typeof globalThis,
1064
- handler: (event: PopsDOMUtils_Event["keyup"]) => void,
1065
- option?: boolean | AddEventListenerOptions
1066
- ) {
1067
- let DOMUtilsContext = this;
1068
- if (target == null) {
1069
- return;
1070
- }
1071
- if (typeof target === "string") {
1072
- target = PopsCore.document.querySelector(target) as HTMLElement;
1073
- }
1074
- DOMUtilsContext.on(target, "keyup", null, handler, option);
1075
- }
1076
- /**
1077
- * 当按键按下时触发事件
1078
- * keydown - > keypress - > keyup
1079
- * @param target 目标
1080
- * @param handler 事件处理函数
1081
- * @param option 配置
1082
- * @example
1083
- * // 监听a.xx元素的按键按下
1084
- * DOMUtils.keydown(document.querySelector("a.xx"),()=>{
1085
- * console.log("按键按下");
1086
- * })
1087
- * DOMUtils.keydown("a.xx",()=>{
1088
- * console.log("按键按下");
1089
- * })
1090
- */
1091
- keydown(
1092
- target: HTMLElement | Window | typeof globalThis | string,
1093
- handler: (event: PopsDOMUtils_Event["keydown"]) => void,
1094
- option?: boolean | AddEventListenerOptions
1095
- ) {
1096
- let DOMUtilsContext = this;
1097
- if (target == null) {
1098
- return;
1099
- }
1100
- if (typeof target === "string") {
1101
- target = PopsCore.document.querySelector(target) as HTMLElement;
1102
- }
1103
- DOMUtilsContext.on(target, "keydown", null, handler, option);
1104
- }
1105
- /**
1106
- * 当按键按下时触发事件
1107
- * keydown - > keypress - > keyup
1108
- * @param target 目标
1109
- * @param handler 事件处理函数
1110
- * @param option 配置
1111
- * @example
1112
- * // 监听a.xx元素的按键按下
1113
- * DOMUtils.keypress(document.querySelector("a.xx"),()=>{
1114
- * console.log("按键按下");
1115
- * })
1116
- * DOMUtils.keypress("a.xx",()=>{
1117
- * console.log("按键按下");
1118
- * })
1119
- */
1120
- keypress(
1121
- target: HTMLElement | Window | typeof globalThis | string,
1122
- handler: (event: PopsDOMUtils_Event["keypress"]) => void,
1123
- option?: boolean | AddEventListenerOptions
1124
- ) {
1125
- let DOMUtilsContext = this;
1126
- if (target == null) {
1127
- return;
1128
- }
1129
- if (typeof target === "string") {
1130
- target = PopsCore.document.querySelector(target) as HTMLElement;
1131
- }
1132
- DOMUtilsContext.on(target, "keypress", null, handler, option);
1133
- }
1134
-
1135
- /**
1136
- * 阻止事件传递
1137
- * @param element 要进行处理的元素
1138
- * @param eventNameList (可选)要阻止的事件名|列表
1139
- * @param capture (可选)是否捕获,默认false
1140
- * @example
1141
- * Utils.preventEvent(document.querySelector("a"),"click")
1142
- * @example
1143
- * Utils.preventEvent(event);
1144
- */
1145
- preventEvent(event: Event): boolean;
1146
- /**
1147
- * 阻止事件传递
1148
- * @param element 要进行处理的元素
1149
- * @param eventNameList (可选)要阻止的事件名|列表
1150
- * @param capture (可选)是否捕获,默认false
1151
- * @example
1152
- * Utils.preventEvent(document.querySelector("a"),"click")
1153
- * @example
1154
- * Utils.preventEvent(event);
1155
- */
1156
- preventEvent(
1157
- element: HTMLElement,
1158
- eventNameList?: string | string[],
1159
- capture?: boolean
1160
- ): boolean;
1161
- preventEvent(
1162
- element: HTMLElement | Event,
1163
- eventNameList: string | string[] = [],
1164
- capture?: boolean
1165
- ): boolean | undefined {
1166
- function stopEvent(event: Event) {
1167
- /* 阻止事件的默认行为发生。例如,当点击一个链接时,浏览器会默认打开链接的URL */
1168
- event?.preventDefault();
1169
- /* 停止事件的传播,阻止它继续向更上层的元素冒泡,事件将不会再传播给其他的元素 */
1170
- event?.stopPropagation();
1171
- /* 阻止事件传播,并且还能阻止元素上的其他事件处理程序被触发 */
1172
- event?.stopImmediatePropagation();
1173
- return false;
1174
- }
1175
- if (arguments.length === 1) {
1176
- /* 直接阻止事件 */
1177
- return stopEvent(arguments[0]);
1178
- } else {
1179
- /* 添加对应的事件来阻止触发 */
1180
- if (typeof eventNameList === "string") {
1181
- eventNameList = [eventNameList];
1182
- }
1183
- eventNameList.forEach((eventName) => {
1184
- (element as HTMLElement).addEventListener(eventName, stopEvent, {
1185
- capture: Boolean(capture),
1186
- });
1187
- });
1188
- }
1189
- }
1190
- /**
1191
- * 选择器,可使用以下的额外语法
1192
- *
1193
- * + :contains([text]) 作用: 找到包含指定文本内容的指定元素
1194
- * + :empty 作用:找到既没有文本内容也没有子元素的指定元素
1195
- * + :regexp([text]) 作用: 找到符合正则表达式的内容的指定元素
1196
- * @param selector 选择器
1197
- * @example
1198
- * DOMUtils.selector("div:contains('测试')")
1199
- * > div.xxx
1200
- * @example
1201
- * DOMUtils.selector("div:empty")
1202
- * > div.xxx
1203
- * @example
1204
- * DOMUtils.selector("div:regexp('^xxxx$')")
1205
- * > div.xxx
1206
- */
1207
- selector<K extends keyof HTMLElementTagNameMap>(
1208
- selector: K
1209
- ): HTMLElementTagNameMap[K] | undefined;
1210
- selector<E extends Element = Element>(selector: string): E | undefined;
1211
- selector<E extends Element = Element>(selector: string) {
1212
- return this.selectorAll<E>(selector)[0];
1213
- }
1214
- /**
1215
- * 选择器,可使用以下的额外语法
1216
- *
1217
- * + :contains([text]) 作用: 找到包含指定文本内容的指定元素
1218
- * + :empty 作用:找到既没有文本内容也没有子元素的指定元素
1219
- * + :regexp([text]) 作用: 找到符合正则表达式的内容的指定元素
1220
- * @param selector 选择器
1221
- * @example
1222
- * DOMUtils.selectorAll("div:contains('测试')")
1223
- * > [div.xxx]
1224
- * @example
1225
- * DOMUtils.selectorAll("div:empty")
1226
- * > [div.xxx]
1227
- * @example
1228
- * DOMUtils.selectorAll("div:regexp('^xxxx$')")
1229
- * > [div.xxx]
1230
- * @example
1231
- * DOMUtils.selectorAll("div:regexp(/^xxx/ig)")
1232
- * > [div.xxx]
1233
- */
1234
- selectorAll<K extends keyof HTMLElementTagNameMap>(
1235
- selector: K
1236
- ): HTMLElementTagNameMap[K][];
1237
- selectorAll<E extends Element = Element>(selector: string): E[];
1238
- selectorAll<E extends Element = Element>(selector: string) {
1239
- selector = selector.trim();
1240
- if (selector.match(/[^\s]{1}:empty$/gi)) {
1241
- // empty 语法
1242
- selector = selector.replace(/:empty$/gi, "");
1243
- return Array.from(PopsCore.document.querySelectorAll<E>(selector)).filter(
1244
- ($ele) => {
1245
- return $ele?.innerHTML?.trim() === "";
1246
- }
1247
- );
1248
- } else if (
1249
- selector.match(/[^\s]{1}:contains\("(.*)"\)$/i) ||
1250
- selector.match(/[^\s]{1}:contains\('(.*)'\)$/i)
1251
- ) {
1252
- // contains 语法
1253
- let textMatch = selector.match(/:contains\(("|')(.*)("|')\)$/i);
1254
- let text = textMatch![2];
1255
- selector = selector.replace(/:contains\(("|')(.*)("|')\)$/gi, "");
1256
- return Array.from(PopsCore.document.querySelectorAll<E>(selector)).filter(
1257
- ($ele) => {
1258
- // @ts-ignore
1259
- return ($ele?.textContent || $ele?.innerText)?.includes(text);
1260
- }
1261
- );
1262
- } else if (
1263
- selector.match(/[^\s]{1}:regexp\("(.*)"\)$/i) ||
1264
- selector.match(/[^\s]{1}:regexp\('(.*)'\)$/i)
1265
- ) {
1266
- // regexp 语法
1267
- let textMatch = selector.match(/:regexp\(("|')(.*)("|')\)$/i);
1268
- let pattern = textMatch![2];
1269
- let flagMatch = pattern.match(/("|'),[\s]*("|')([igm]{0,3})$/i);
1270
- let flags = "";
1271
- if (flagMatch) {
1272
- pattern = pattern.replace(/("|'),[\s]*("|')([igm]{0,3})$/gi, "");
1273
- flags = flagMatch[3];
1274
- }
1275
- let regexp = new RegExp(pattern, flags);
1276
- selector = selector.replace(/:regexp\(("|')(.*)("|')\)$/gi, "");
1277
- return Array.from(PopsCore.document.querySelectorAll<E>(selector)).filter(
1278
- ($ele) => {
1279
- // @ts-ignore
1280
- return Boolean(($ele?.textContent || $ele?.innerText)?.match(regexp));
1281
- }
1282
- );
1283
- } else {
1284
- // 普通语法
1285
- return Array.from(PopsCore.document.querySelectorAll<E>(selector));
1286
- }
1287
- }
1288
- /**
1289
- * 匹配元素,可使用以下的额外语法
1290
- *
1291
- * + :contains([text]) 作用: 找到包含指定文本内容的指定元素
1292
- * + :empty 作用:找到既没有文本内容也没有子元素的指定元素
1293
- * + :regexp([text]) 作用: 找到符合正则表达式的内容的指定元素
1294
- * @param $el 元素
1295
- * @param selector 选择器
1296
- * @example
1297
- * DOMUtils.matches("div:contains('测试')")
1298
- * > true
1299
- * @example
1300
- * DOMUtils.matches("div:empty")
1301
- * > true
1302
- * @example
1303
- * DOMUtils.matches("div:regexp('^xxxx$')")
1304
- * > true
1305
- * @example
1306
- * DOMUtils.matches("div:regexp(/^xxx/ig)")
1307
- * > false
1308
- */
1309
- matches(
1310
- $el: HTMLElement | Element | null | undefined,
1311
- selector: string
1312
- ): boolean {
1313
- selector = selector.trim();
1314
- if ($el == null) {
1315
- return false;
1316
- }
1317
-
1318
- if (selector.match(/[^\s]{1}:empty$/gi)) {
1319
- // empty 语法
1320
- selector = selector.replace(/:empty$/gi, "");
1321
- return $el.matches(selector) && $el?.innerHTML?.trim() === "";
1322
- } else if (
1323
- selector.match(/[^\s]{1}:contains\("(.*)"\)$/i) ||
1324
- selector.match(/[^\s]{1}:contains\('(.*)'\)$/i)
1325
- ) {
1326
- // contains 语法
1327
- let textMatch = selector.match(/:contains\(("|')(.*)("|')\)$/i);
1328
- let text = textMatch![2];
1329
- selector = selector.replace(/:contains\(("|')(.*)("|')\)$/gi, "");
1330
- // @ts-ignore
1331
- let content = $el?.textContent || $el?.innerText;
1332
- if (typeof content !== "string") {
1333
- content = "";
1334
- }
1335
- return $el.matches(selector) && content?.includes(text);
1336
- } else if (
1337
- selector.match(/[^\s]{1}:regexp\("(.*)"\)$/i) ||
1338
- selector.match(/[^\s]{1}:regexp\('(.*)'\)$/i)
1339
- ) {
1340
- // regexp 语法
1341
- let textMatch = selector.match(/:regexp\(("|')(.*)("|')\)$/i);
1342
- let pattern = textMatch![2];
1343
- let flagMatch = pattern.match(/("|'),[\s]*("|')([igm]{0,3})$/i);
1344
- let flags = "";
1345
- if (flagMatch) {
1346
- pattern = pattern.replace(/("|'),[\s]*("|')([igm]{0,3})$/gi, "");
1347
- flags = flagMatch[3];
1348
- }
1349
- let regexp = new RegExp(pattern, flags);
1350
- selector = selector.replace(/:regexp\(("|')(.*)("|')\)$/gi, "");
1351
- // @ts-ignore
1352
- let content = $el?.textContent || $el?.innerText;
1353
- if (typeof content !== "string") {
1354
- content = "";
1355
- }
1356
- return $el.matches(selector) && Boolean(content?.match(regexp));
1357
- } else {
1358
- // 普通语法
1359
- return $el.matches(selector);
1360
- }
1361
- }
1362
- /**
1363
- * 根据选择器获取上层元素,可使用以下的额外语法
1364
- *
1365
- * + :contains([text]) 作用: 找到包含指定文本内容的指定元素
1366
- * + :empty 作用:找到既没有文本内容也没有子元素的指定元素
1367
- * + :regexp([text]) 作用: 找到符合正则表达式的内容的指定元素
1368
- * @param $el 元素
1369
- * @param selector 选择器
1370
- * @example
1371
- * DOMUtils.closest("div:contains('测试')")
1372
- * > div.xxx
1373
- * @example
1374
- * DOMUtils.closest("div:empty")
1375
- * > div.xxx
1376
- * @example
1377
- * DOMUtils.closest("div:regexp('^xxxx$')")
1378
- * > div.xxxx
1379
- * @example
1380
- * DOMUtils.closest("div:regexp(/^xxx/ig)")
1381
- * > null
1382
- */
1383
- closest<K extends keyof HTMLElementTagNameMap>(
1384
- $el: HTMLElement | Element,
1385
- selector: string
1386
- ): HTMLElementTagNameMap[K] | null;
1387
- closest<E extends Element = Element>(
1388
- $el: HTMLElement | Element,
1389
- selector: string
1390
- ): E | null;
1391
- closest<E extends Element = Element>(
1392
- $el: HTMLElement | Element,
1393
- selector: string
1394
- ): E | null {
1395
- selector = selector.trim();
1396
-
1397
- if (selector.match(/[^\s]{1}:empty$/gi)) {
1398
- // empty 语法
1399
- selector = selector.replace(/:empty$/gi, "");
1400
- let $closest = $el?.closest<E>(selector);
1401
- if ($closest && $closest?.innerHTML?.trim() === "") {
1402
- return $closest;
1403
- }
1404
- return null;
1405
- } else if (
1406
- selector.match(/[^\s]{1}:contains\("(.*)"\)$/i) ||
1407
- selector.match(/[^\s]{1}:contains\('(.*)'\)$/i)
1408
- ) {
1409
- // contains 语法
1410
- let textMatch = selector.match(/:contains\(("|')(.*)("|')\)$/i);
1411
- let text = textMatch![2];
1412
- selector = selector.replace(/:contains\(("|')(.*)("|')\)$/gi, "");
1413
- let $closest = $el?.closest<E>(selector);
1414
- if ($closest) {
1415
- // @ts-ignore
1416
- let content = $el?.textContent || $el?.innerText;
1417
- if (typeof content === "string" && content.includes(text)) {
1418
- return $closest;
1419
- }
1420
- }
1421
- return null;
1422
- } else if (
1423
- selector.match(/[^\s]{1}:regexp\("(.*)"\)$/i) ||
1424
- selector.match(/[^\s]{1}:regexp\('(.*)'\)$/i)
1425
- ) {
1426
- // regexp 语法
1427
- let textMatch = selector.match(/:regexp\(("|')(.*)("|')\)$/i);
1428
- let pattern = textMatch![2];
1429
- let flagMatch = pattern.match(/("|'),[\s]*("|')([igm]{0,3})$/i);
1430
- let flags = "";
1431
- if (flagMatch) {
1432
- pattern = pattern.replace(/("|'),[\s]*("|')([igm]{0,3})$/gi, "");
1433
- flags = flagMatch[3];
1434
- }
1435
- let regexp = new RegExp(pattern, flags);
1436
- selector = selector.replace(/:regexp\(("|')(.*)("|')\)$/gi, "");
1437
- let $closest = $el?.closest<E>(selector);
1438
- if ($closest) {
1439
- // @ts-ignore
1440
- let content = $el?.textContent || $el?.innerText;
1441
- if (typeof content === "string" && content.match(regexp)) {
1442
- return $closest;
1443
- }
1444
- }
1445
- return null;
1446
- } else {
1447
- // 普通语法
1448
- let $closest = $el?.closest<E>(selector);
1449
- return $closest;
1450
- }
1451
- }
1452
- }
1453
-
1454
- class PopsDOMUtils extends PopsDOMUtilsEvent {
1455
- /** 获取 animationend 在各个浏览器的兼容名 */
1456
- getAnimationEndNameList() {
1457
- return [
1458
- "webkitAnimationEnd",
1459
- "mozAnimationEnd",
1460
- "MSAnimationEnd",
1461
- "oanimationend",
1462
- "animationend",
1463
- ];
1464
- }
1465
- /** 获取 transitionend 在各个浏览器的兼容名 */
1466
- getTransitionEndNameList() {
1467
- return [
1468
- "webkitTransitionEnd",
1469
- "mozTransitionEnd",
1470
- "MSTransitionEnd",
1471
- "otransitionend",
1472
- "transitionend",
1473
- ];
1474
- }
1475
- /**
1476
- * 实现jQuery中的$().offset();
1477
- * @param element
1478
- * @param calcScroll 计算滚动距离
1479
- */
1480
- offset(element: HTMLElement, calcScroll: boolean = true) {
1481
- let rect = element.getBoundingClientRect();
1482
- let win = element.ownerDocument.defaultView;
1483
- let resultRect = new DOMRect(
1484
- calcScroll
1485
- ? parseFloat((rect.left + (win?.pageXOffset || 0)).toString())
1486
- : rect.left,
1487
- calcScroll
1488
- ? parseFloat((rect.top + (win?.pageYOffset || 0)).toString())
1489
- : rect.top,
1490
- rect.width,
1491
- rect.height
1492
- );
1493
- return resultRect;
1494
- }
1495
- /**
1496
- * 获取元素的宽度
1497
- * @param element 要获取宽度的元素
1498
- * @param isShow 是否已进行isShow,避免爆堆栈
1499
- * @param parent 用于判断是否已显示的父元素载体
1500
- * @returns 元素的宽度,单位为像素
1501
- * @example
1502
- * // 获取元素a.xx的宽度
1503
- * DOMUtils.width(document.querySelector("a.xx"))
1504
- * DOMUtils.width("a.xx")
1505
- * > 100
1506
- * // 获取window的宽度
1507
- * DOMUtils.width(window)
1508
- * > 400
1509
- * @example
1510
- * // 设置元素a.xx的宽度为200
1511
- * DOMUtils.width(document.querySelector("a.xx"),200)
1512
- * DOMUtils.width("a.xx",200)
1513
- */
1514
- width(
1515
- element: HTMLElement | string | Window | Document | typeof globalThis,
1516
- isShow?: boolean,
1517
- parent?: HTMLElement | ShadowRoot
1518
- ): number;
1519
- width(
1520
- element: HTMLElement | string | Window | Document | typeof globalThis,
1521
- isShow: boolean = false,
1522
- parent?: HTMLElement | ShadowRoot
1523
- ) {
1524
- let DOMUtilsContext = this;
1525
- if (typeof element === "string") {
1526
- element = PopsCore.document.querySelector(element) as HTMLElement;
1527
- }
1528
- if (element == null) {
1529
- return;
1530
- }
1531
- if (popsUtils.isWin(element)) {
1532
- return PopsCore.window.document.documentElement.clientWidth;
1533
- }
1534
- if ((element as HTMLElement).nodeType === 9) {
1535
- /* Document文档节点 */
1536
- element = element as Document;
1537
- return Math.max(
1538
- element.body.scrollWidth,
1539
- element.documentElement.scrollWidth,
1540
- element.body.offsetWidth,
1541
- element.documentElement.offsetWidth,
1542
- element.documentElement.clientWidth
1543
- );
1544
- }
1545
- if (isShow || (!isShow && popsDOMUtils.isShow(element as HTMLElement))) {
1546
- /* 已显示 */
1547
- /* 不从style中获取对应的宽度,因为可能使用了class定义了width !important */
1548
- element = element as HTMLElement;
1549
- /* 如果element.style.width为空 则从css里面获取是否定义了width信息如果定义了 则读取css里面定义的宽度width */
1550
- if (
1551
- parseFloat(popsDOMUtils.getStyleValue(element, "width").toString()) > 0
1552
- ) {
1553
- return parseFloat(
1554
- popsDOMUtils.getStyleValue(element, "width").toString()
1555
- );
1556
- }
1557
-
1558
- /* 如果从css里获取到的值不是大于0 可能是auto 则通过offsetWidth来进行计算 */
1559
- if (element.offsetWidth > 0) {
1560
- let borderLeftWidth = popsDOMUtils.getStyleValue(
1561
- element,
1562
- "borderLeftWidth"
1563
- );
1564
- let borderRightWidth = popsDOMUtils.getStyleValue(
1565
- element,
1566
- "borderRightWidth"
1567
- );
1568
- let paddingLeft = popsDOMUtils.getStyleValue(element, "paddingLeft");
1569
- let paddingRight = popsDOMUtils.getStyleValue(element, "paddingRight");
1570
- let backHeight =
1571
- parseFloat(element.offsetWidth.toString()) -
1572
- parseFloat(borderLeftWidth.toString()) -
1573
- parseFloat(borderRightWidth.toString()) -
1574
- parseFloat(paddingLeft.toString()) -
1575
- parseFloat(paddingRight.toString());
1576
- return parseFloat(backHeight.toString());
1577
- }
1578
- return 0;
1579
- } else {
1580
- /* 未显示 */
1581
- element = element as HTMLElement;
1582
- let { cloneNode, recovery } = popsDOMUtils.showElement(element, parent);
1583
- let width = DOMUtilsContext.width(cloneNode, true, parent);
1584
- recovery();
1585
- return width;
1586
- }
1587
- }
1588
-
1589
- /**
1590
- * 获取元素的高度
1591
- * @param element 要获取高度的元素
1592
- * @param isShow 是否已进行isShow,避免爆堆栈
1593
- * @param parent 用于判断是否已显示的父元素载体
1594
- * @returns 元素的高度,单位为像素
1595
- * @example
1596
- * // 获取元素a.xx的高度
1597
- * DOMUtils.height(document.querySelector("a.xx"))
1598
- * DOMUtils.height("a.xx")
1599
- * > 100
1600
- * // 获取window的高度
1601
- * DOMUtils.height(window)
1602
- * > 700
1603
- * @example
1604
- * // 设置元素a.xx的高度为200
1605
- * DOMUtils.height(document.querySelector("a.xx"),200)
1606
- * DOMUtils.height("a.xx",200)
1607
- */
1608
- height(
1609
- element: HTMLElement | string | Window | Document | typeof globalThis,
1610
- isShow?: boolean,
1611
- parent?: HTMLElement | ShadowRoot
1612
- ): number;
1613
- height(
1614
- element: HTMLElement | string | Window | Document | typeof globalThis,
1615
- isShow: boolean = false,
1616
- parent?: HTMLElement | ShadowRoot
1617
- ) {
1618
- let DOMUtilsContext = this;
1619
- if (popsUtils.isWin(element)) {
1620
- return PopsCore.window.document.documentElement.clientHeight;
1621
- }
1622
- if (typeof element === "string") {
1623
- element = PopsCore.document.querySelector(element) as HTMLElement;
1624
- }
1625
- if (element == null) {
1626
- return;
1627
- }
1628
- if ((element as Document).nodeType === 9) {
1629
- element = element as Document;
1630
- /* Document文档节点 */
1631
- return Math.max(
1632
- element.body.scrollHeight,
1633
- element.documentElement.scrollHeight,
1634
- element.body.offsetHeight,
1635
- element.documentElement.offsetHeight,
1636
- element.documentElement.clientHeight
1637
- );
1638
- }
1639
- if (isShow || (!isShow && popsDOMUtils.isShow(element as HTMLElement))) {
1640
- element = element as HTMLElement;
1641
- /* 已显示 */
1642
- /* 从style中获取对应的高度,因为可能使用了class定义了width !important */
1643
- /* 如果element.style.height为空 则从css里面获取是否定义了height信息如果定义了 则读取css里面定义的高度height */
1644
- if (
1645
- parseFloat(popsDOMUtils.getStyleValue(element, "height").toString()) > 0
1646
- ) {
1647
- return parseFloat(
1648
- popsDOMUtils.getStyleValue(element, "height").toString()
1649
- );
1650
- }
1651
-
1652
- /* 如果从css里获取到的值不是大于0 可能是auto 则通过offsetHeight来进行计算 */
1653
- if (element.offsetHeight > 0) {
1654
- let borderTopWidth = popsDOMUtils.getStyleValue(
1655
- element,
1656
- "borderTopWidth"
1657
- );
1658
- let borderBottomWidth = popsDOMUtils.getStyleValue(
1659
- element,
1660
- "borderBottomWidth"
1661
- );
1662
- let paddingTop = popsDOMUtils.getStyleValue(element, "paddingTop");
1663
- let paddingBottom = popsDOMUtils.getStyleValue(
1664
- element,
1665
- "paddingBottom"
1666
- );
1667
- let backHeight =
1668
- parseFloat(element.offsetHeight.toString()) -
1669
- parseFloat(borderTopWidth.toString()) -
1670
- parseFloat(borderBottomWidth.toString()) -
1671
- parseFloat(paddingTop.toString()) -
1672
- parseFloat(paddingBottom.toString());
1673
- return parseFloat(backHeight.toString());
1674
- }
1675
- return 0;
1676
- } else {
1677
- /* 未显示 */
1678
- element = element as HTMLElement;
1679
- let { cloneNode, recovery } = popsDOMUtils.showElement(element, parent);
1680
- let height = DOMUtilsContext.height(cloneNode, true, parent);
1681
- recovery();
1682
- return height;
1683
- }
1684
- }
1685
- /**
1686
- * 获取元素的外部宽度(包括边框和外边距)
1687
- * @param element 要获取外部宽度的元素
1688
- * @param 是否已进行isShow,避免爆堆栈
1689
- * @param parent 用于判断是否已显示的父元素载体
1690
- * @returns 元素的外部宽度,单位为像素
1691
- * @example
1692
- * // 获取元素a.xx的外部宽度
1693
- * DOMUtils.outerWidth(document.querySelector("a.xx"))
1694
- * DOMUtils.outerWidth("a.xx")
1695
- * > 100
1696
- * // 获取window的外部宽度
1697
- * DOMUtils.outerWidth(window)
1698
- * > 400
1699
- */
1700
- outerWidth(
1701
- element: HTMLElement | string | Window | Document,
1702
- isShow?: boolean,
1703
- parent?: HTMLElement | ShadowRoot
1704
- ): number;
1705
- outerWidth(
1706
- element: HTMLElement | string | Window | Document,
1707
- isShow: boolean = false,
1708
- parent?: HTMLElement | ShadowRoot
1709
- ) {
1710
- let DOMUtilsContext = this;
1711
- if (popsUtils.isWin(element)) {
1712
- return PopsCore.window.innerWidth;
1713
- }
1714
- if (typeof element === "string") {
1715
- element = PopsCore.document.querySelector(element) as HTMLElement;
1716
- }
1717
- if (element == null) {
1718
- return;
1719
- }
1720
- element = element as HTMLElement;
1721
- if (isShow || (!isShow && popsDOMUtils.isShow(element))) {
1722
- let style = getComputedStyle(element, null);
1723
- let marginLeft = popsDOMUtils.getStyleValue(style, "marginLeft");
1724
- let marginRight = popsDOMUtils.getStyleValue(style, "marginRight");
1725
- return element.offsetWidth + marginLeft + marginRight;
1726
- } else {
1727
- let { cloneNode, recovery } = popsDOMUtils.showElement(element, parent);
1728
- let outerWidth = DOMUtilsContext.outerWidth(cloneNode, true, parent);
1729
- recovery();
1730
- return outerWidth;
1731
- }
1732
- }
1733
- /**
1734
- * 获取元素的外部高度(包括边框和外边距)
1735
- * @param element 要获取外部高度的元素
1736
- * @param isShow 是否已进行isShow,避免爆堆栈
1737
- * @param parent 用于判断是否已显示的父元素载体
1738
- * @returns 元素的外部高度,单位为像素
1739
- * @example
1740
- * // 获取元素a.xx的外部高度
1741
- * DOMUtils.outerHeight(document.querySelector("a.xx"))
1742
- * DOMUtils.outerHeight("a.xx")
1743
- * > 100
1744
- * // 获取window的外部高度
1745
- * DOMUtils.outerHeight(window)
1746
- * > 700
1747
- */
1748
- outerHeight(
1749
- element: HTMLElement | string | Window,
1750
- isShow?: boolean,
1751
- parent?: HTMLElement | ShadowRoot
1752
- ): number;
1753
- outerHeight(
1754
- element: HTMLElement | string | Window,
1755
- isShow: boolean = false,
1756
- parent?: HTMLElement | ShadowRoot
1757
- ): number {
1758
- let DOMUtilsContext = this;
1759
- if (popsUtils.isWin(element)) {
1760
- return PopsCore.window.innerHeight;
1761
- }
1762
- if (typeof element === "string") {
1763
- element = PopsCore.document.querySelector(element) as HTMLElement;
1764
- }
1765
- if (element == null) {
1766
- // @ts-ignore
1767
- return;
1768
- }
1769
- element = element as HTMLElement;
1770
- if (isShow || (!isShow && popsDOMUtils.isShow(element))) {
1771
- let style = getComputedStyle(element, null);
1772
- let marginTop = popsDOMUtils.getStyleValue(style, "marginTop");
1773
- let marginBottom = popsDOMUtils.getStyleValue(style, "marginBottom");
1774
- return element.offsetHeight + marginTop + marginBottom;
1775
- } else {
1776
- let { cloneNode, recovery } = popsDOMUtils.showElement(element, parent);
1777
- let outerHeight = DOMUtilsContext.outerHeight(cloneNode, true, parent);
1778
- recovery();
1779
- return outerHeight;
1780
- }
1781
- }
1782
- /**
1783
- * 添加className
1784
- * @param element 目标元素
1785
- * @param className className属性
1786
- */
1787
- addClassName(element: Element | undefined | null, className: string) {
1788
- if (element == null) {
1789
- return;
1790
- }
1791
- if (typeof className !== "string") {
1792
- return;
1793
- }
1794
- if (className.trim() === "") {
1795
- return;
1796
- }
1797
- element.classList.add(className);
1798
- }
1799
- /**
1800
- * 删除className
1801
- * @param element 目标元素
1802
- * @param className className属性
1803
- */
1804
- removeClassName(element: Element | undefined | null, className: string) {
1805
- if (element == null) {
1806
- return;
1807
- }
1808
- if (typeof className !== "string") {
1809
- return;
1810
- }
1811
- if (className.trim() === "") {
1812
- return;
1813
- }
1814
- element.classList.remove(className);
1815
- }
1816
- /**
1817
- * 判断元素是否包含某个className
1818
- * @param element 目标元素
1819
- * @param className className属性
1820
- */
1821
- containsClassName(
1822
- element: HTMLElement | undefined | null,
1823
- className: string
1824
- ): boolean {
1825
- if (element == null) {
1826
- return false;
1827
- }
1828
- if (typeof className !== "string") {
1829
- return false;
1830
- }
1831
- if (className.trim() === "") {
1832
- return false;
1833
- }
1834
- return element.classList.contains(className);
1835
- }
1836
- /**
1837
- * 获取元素的样式属性值
1838
- * @param element 目标元素
1839
- * @param property 样式属性名或包含多个属性名和属性值的对象
1840
- * @example
1841
- * // 获取元素a.xx的CSS属性display
1842
- * DOMUtils.css(document.querySelector("a.xx"),"display");
1843
- * DOMUtils.css("a.xx","display");
1844
- * > "none"
1845
- * */
1846
- css(
1847
- element: HTMLElement | string,
1848
- property: keyof CSSStyleDeclaration
1849
- ): string;
1850
- /**
1851
- * 获取元素的样式属性值
1852
- * @param element 目标元素
1853
- * @param property 样式属性名或包含多个属性名和属性值的对象
1854
- * @example
1855
- * // 获取元素a.xx的CSS属性display
1856
- * DOMUtils.css(document.querySelector("a.xx"),"display");
1857
- * DOMUtils.css("a.xx","display");
1858
- * > "none"
1859
- * */
1860
- css(element: HTMLElement | string, property: string): string;
1861
- /**
1862
- * 设置元素的样式属性
1863
- * @param element 目标元素
1864
- * @param property 样式属性名或包含多个属性名和属性值的对象
1865
- * @param value 样式属性值
1866
- * @example
1867
- * // 设置元素a.xx的CSS属性display为block
1868
- * DOMUtils.css(document.querySelector("a.xx"),"display","block");
1869
- * DOMUtils.css(document.querySelector("a.xx"),"display","block !important");
1870
- * DOMUtils.css("a.xx","display","block");
1871
- * DOMUtils.css("a.xx","display","block !important");
1872
- * @example
1873
- * // 设置元素a.xx的CSS属性top为10px
1874
- * DOMUtils.css(document.querySelector("a.xx"),"top","10px");
1875
- * DOMUtils.css(document.querySelector("a.xx"),"top",10);
1876
- * */
1877
- css(
1878
- element: HTMLElement | string,
1879
- property: keyof CSSStyleDeclaration & string,
1880
- value: string | number
1881
- ): string;
1882
- /**
1883
- * 设置元素的样式属性
1884
- * @param element 目标元素
1885
- * @param property 样式属性名或包含多个属性名和属性值的对象
1886
- * @param value 样式属性值
1887
- * @example
1888
- * // 设置元素a.xx的CSS属性display为block
1889
- * DOMUtils.css(document.querySelector("a.xx"),{ display: "block" }});
1890
- * DOMUtils.css(document.querySelector("a.xx"),{ display: "block !important" }});
1891
- * @example
1892
- * // 设置元素a.xx的CSS属性top为10px
1893
- * DOMUtils.css(document.querySelector("a.xx"),{ top: "10px" });
1894
- * DOMUtils.css(document.querySelector("a.xx"),{ top: 10 });
1895
- * */
1896
- css(
1897
- element: HTMLElement | string,
1898
- property:
1899
- | {
1900
- [P in keyof CSSStyleDeclaration]?: CSSStyleDeclaration[P];
1901
- }
1902
- | {
1903
- [key: string]: string | number;
1904
- }
1905
- ): string;
1906
- css(
1907
- element: HTMLElement | string,
1908
- property:
1909
- | keyof CSSStyleDeclaration
1910
- | string
1911
- | {
1912
- [P in keyof CSSStyleDeclaration]?:
1913
- | string
1914
- | number
1915
- | CSSStyleDeclaration[P];
1916
- },
1917
- value?: string | number
1918
- ) {
1919
- /**
1920
- * 把纯数字没有px的加上
1921
- */
1922
- function handlePixe(propertyName: string, propertyValue: string | number) {
1923
- let allowAddPixe = [
1924
- "width",
1925
- "height",
1926
- "top",
1927
- "left",
1928
- "right",
1929
- "bottom",
1930
- "font-size",
1931
- ];
1932
- if (typeof propertyValue === "number") {
1933
- propertyValue = propertyValue.toString();
1934
- }
1935
- if (
1936
- typeof propertyValue === "string" &&
1937
- allowAddPixe.includes(propertyName) &&
1938
- propertyValue.match(/[0-9]$/gi)
1939
- ) {
1940
- propertyValue = propertyValue + "px";
1941
- }
1942
- return propertyValue;
1943
- }
1944
- if (typeof element === "string") {
1945
- element = PopsCore.document.querySelector(element) as HTMLElement;
1946
- }
1947
- if (element == null) {
1948
- return;
1949
- }
1950
- let setStyleProperty = (
1951
- propertyName: string,
1952
- propertyValue: string | number
1953
- ) => {
1954
- if (
1955
- typeof propertyValue === "string" &&
1956
- propertyValue.trim().endsWith("!important")
1957
- ) {
1958
- propertyValue = propertyValue
1959
- .trim()
1960
- .replace(/!important$/gi, "")
1961
- .trim();
1962
- element.style.setProperty(propertyName, propertyValue, "important");
1963
- } else {
1964
- propertyValue = handlePixe(propertyName, propertyValue);
1965
- element.style.setProperty(propertyName, propertyValue);
1966
- }
1967
- };
1968
- if (typeof property === "string") {
1969
- if (value == null) {
1970
- return getComputedStyle(element).getPropertyValue(property);
1971
- } else {
1972
- setStyleProperty(property, value);
1973
- }
1974
- } else if (typeof property === "object") {
1975
- for (let prop in property) {
1976
- let value = property[prop];
1977
- setStyleProperty(prop, value!);
1978
- }
1979
- }
1980
- }
1981
- /**
1982
- * 创建元素
1983
- * @param tagName 标签名
1984
- * @param property 属性
1985
- * @param attributes 元素上的自定义属性
1986
- * @example
1987
- * // 创建一个DIV元素,且属性class为xxx
1988
- * DOMUtils.createElement("div",undefined,{ class:"xxx" });
1989
- * > <div class="xxx"></div>
1990
- * @example
1991
- * // 创建一个DIV元素
1992
- * DOMUtils.createElement("div");
1993
- * > <div></div>
1994
- * @example
1995
- * // 创建一个DIV元素
1996
- * DOMUtils.createElement("div","测试");
1997
- * > <div>测试</div>
1998
- */
1999
- createElement<K extends keyof HTMLElementTagNameMap>(
2000
- /** 元素名 */
2001
- tagName: K,
2002
- /** 属性 */
2003
- property?:
2004
- | ({
2005
- [P in keyof HTMLElementTagNameMap[K]]?: HTMLElementTagNameMap[K][P] extends
2006
- | string
2007
- | boolean
2008
- | number
2009
- ? HTMLElementTagNameMap[K][P]
2010
- : never;
2011
- } & {
2012
- [key: string]: any;
2013
- })
2014
- | string,
2015
- /** 自定义属性 */
2016
- attributes?: PopsDOMUtilsCreateElementAttributesMap
2017
- ): HTMLElementTagNameMap[K] {
2018
- let tempElement = PopsCore.document.createElement(tagName);
2019
- if (typeof property === "string") {
2020
- PopsSafeUtils.setSafeHTML(tempElement, property);
2021
- return tempElement;
2022
- }
2023
- if (property == null) {
2024
- property = {};
2025
- }
2026
- if (attributes == null) {
2027
- attributes = {};
2028
- }
2029
- Object.keys(property).forEach((key) => {
2030
- let value = property[key];
2031
- if (key === "innerHTML") {
2032
- PopsSafeUtils.setSafeHTML(tempElement, value);
2033
- return;
2034
- }
2035
- // @ts-ignore
2036
- tempElement[key] = value;
2037
- });
2038
- Object.keys(attributes).forEach((key) => {
2039
- let value = attributes[key];
2040
- if (typeof value === "object") {
2041
- /* object转字符串 */
2042
- value = JSON.stringify(value);
2043
- } else if (typeof value === "function") {
2044
- /* function转字符串 */
2045
- value = value.toString();
2046
- }
2047
- tempElement.setAttribute(key, value);
2048
- });
2049
- return tempElement;
2050
- }
2051
- /**
2052
- * 字符串转HTMLElement
2053
- * @param elementString
2054
- * @returns
2055
- */
2056
- parseTextToDOM<R extends HTMLElement>(elementString: string): R {
2057
- /* 去除前后的换行和空格 */
2058
- elementString = elementString
2059
- .replace(/^[\n|\s]*/g, "")
2060
- .replace(/[\n|\s]*$/g, "");
2061
- let targetElement = this.createElement("div", {
2062
- innerHTML: elementString,
2063
- });
2064
- return targetElement.firstChild as any as R;
2065
- }
2066
- /**
2067
- * 获取文字的位置信息
2068
- * @param input 输入框
2069
- * @param selectionStart 起始位置
2070
- * @param selectionEnd 结束位置
2071
- * @param debug 是否是调试模式
2072
- * + true 不删除临时节点元素
2073
- * + false 删除临时节点元素
2074
- */
2075
- getTextBoundingRect(
2076
- input: HTMLInputElement | HTMLTextAreaElement,
2077
- selectionStart: number | string,
2078
- selectionEnd: number | string,
2079
- debug: boolean
2080
- ): DOMRect {
2081
- // Basic parameter validation
2082
- if (!input || !("value" in input)) return input;
2083
- if (typeof selectionStart == "string")
2084
- selectionStart = parseFloat(selectionStart);
2085
- if (typeof selectionStart != "number" || isNaN(selectionStart)) {
2086
- selectionStart = 0;
2087
- }
2088
- if (selectionStart < 0) selectionStart = 0;
2089
- else selectionStart = Math.min(input.value.length, selectionStart);
2090
- if (typeof selectionEnd == "string")
2091
- selectionEnd = parseFloat(selectionEnd);
2092
- if (
2093
- typeof selectionEnd != "number" ||
2094
- isNaN(selectionEnd) ||
2095
- selectionEnd < selectionStart
2096
- ) {
2097
- selectionEnd = selectionStart;
2098
- }
2099
- if (selectionEnd < 0) selectionEnd = 0;
2100
- else selectionEnd = Math.min(input.value.length, selectionEnd);
2101
-
2102
- // If available (thus IE), use the createTextRange method
2103
- if (typeof (input as any).createTextRange == "function") {
2104
- var range = (input as any).createTextRange();
2105
- range.collapse(true);
2106
- range.moveStart("character", selectionStart);
2107
- range.moveEnd("character", selectionEnd - selectionStart);
2108
- return range.getBoundingClientRect();
2109
- }
2110
- // createTextRange is not supported, create a fake text range
2111
- var offset = getInputOffset(),
2112
- topPos = offset.top,
2113
- leftPos = offset.left,
2114
- width = getInputCSS("width", true),
2115
- height = getInputCSS("height", true);
2116
-
2117
- // Styles to simulate a node in an input field
2118
- var cssDefaultStyles = "white-space:pre;padding:0;margin:0;",
2119
- listOfModifiers = [
2120
- "direction",
2121
- "font-family",
2122
- "font-size",
2123
- "font-size-adjust",
2124
- "font-variant",
2125
- "font-weight",
2126
- "font-style",
2127
- "letter-spacing",
2128
- "line-height",
2129
- "text-align",
2130
- "text-indent",
2131
- "text-transform",
2132
- "word-wrap",
2133
- "word-spacing",
2134
- ];
2135
- // @ts-ignore
2136
- topPos += getInputCSS<number>("padding-top", true);
2137
- // @ts-ignore
2138
- topPos += getInputCSS("border-top-width", true);
2139
- // @ts-ignore
2140
- leftPos += getInputCSS("padding-left", true);
2141
- // @ts-ignore
2142
- leftPos += getInputCSS("border-left-width", true);
2143
- leftPos += 1; //Seems to be necessary
2144
-
2145
- for (var i = 0; i < listOfModifiers.length; i++) {
2146
- var property = listOfModifiers[i];
2147
- // @ts-ignore
2148
- cssDefaultStyles += property + ":" + getInputCSS(property) + ";";
2149
- }
2150
- // End of CSS variable checks
2151
- // 不能为空,不然获取不到高度
2152
- var text = input.value || "G",
2153
- textLen = text.length,
2154
- fakeClone = document.createElement("div");
2155
- if (selectionStart > 0) appendPart(0, selectionStart);
2156
- var fakeRange = appendPart(selectionStart, selectionEnd);
2157
- if (textLen > selectionEnd) appendPart(selectionEnd, textLen);
2158
-
2159
- // Styles to inherit the font styles of the element
2160
- fakeClone.style.cssText = cssDefaultStyles;
2161
-
2162
- // Styles to position the text node at the desired position
2163
- fakeClone.style.position = "absolute";
2164
- fakeClone.style.top = topPos + "px";
2165
- fakeClone.style.left = leftPos + "px";
2166
- fakeClone.style.width = width + "px";
2167
- fakeClone.style.height = height + "px";
2168
- PopsCore.document.body.appendChild(fakeClone);
2169
- var returnValue = fakeRange.getBoundingClientRect(); //Get rect
2170
-
2171
- if (!debug) fakeClone.parentNode!.removeChild(fakeClone); //Remove temp
2172
- return returnValue;
2173
-
2174
- // Local functions for readability of the previous code
2175
- /**
2176
- *
2177
- * @param start
2178
- * @param end
2179
- */
2180
- function appendPart(start: number, end: number): HTMLSpanElement {
2181
- var span = document.createElement("span");
2182
- span.style.cssText = cssDefaultStyles; //Force styles to prevent unexpected results
2183
- span.textContent = text.substring(start, end);
2184
- fakeClone.appendChild(span);
2185
- return span;
2186
- }
2187
- // Computing offset position
2188
- function getInputOffset() {
2189
- var body = document.body,
2190
- win = document.defaultView,
2191
- docElem = document.documentElement,
2192
- box = document.createElement("div");
2193
- box.style.paddingLeft = box.style.width = "1px";
2194
- body.appendChild(box);
2195
- var isBoxModel = box.offsetWidth == 2;
2196
- body.removeChild(box);
2197
- // @ts-ignore
2198
- box = input.getBoundingClientRect();
2199
- var clientTop = docElem.clientTop || body.clientTop || 0,
2200
- clientLeft = docElem.clientLeft || body.clientLeft || 0,
2201
- scrollTop =
2202
- // @ts-ignore
2203
- win.pageYOffset ||
2204
- (isBoxModel && docElem.scrollTop) ||
2205
- body.scrollTop,
2206
- scrollLeft =
2207
- // @ts-ignore
2208
- win.pageXOffset ||
2209
- (isBoxModel && docElem.scrollLeft) ||
2210
- body.scrollLeft;
2211
- return {
2212
- // @ts-ignore
2213
- top: box.top + scrollTop - clientTop,
2214
- // @ts-ignore
2215
- left: box.left + scrollLeft - clientLeft,
2216
- };
2217
- }
2218
- /**
2219
- *
2220
- * @param prop
2221
- * @param isnumber
2222
- * @returns
2223
- */
2224
- function getInputCSS(prop: string, isnumber: boolean) {
2225
- var val = PopsCore.document
2226
- .defaultView!.getComputedStyle(input, null)
2227
- .getPropertyValue(prop);
2228
- // @ts-ignore
2229
- return isnumber ? parseFloat(val) : val;
2230
- }
2231
- }
2232
- /**
2233
- * 使用className来隐藏元素
2234
- * @param ele
2235
- * @param isImportant 是否使用!important
2236
- */
2237
- cssHide(ele: Element | null, isImportant = false) {
2238
- if (ele == null) {
2239
- return;
2240
- }
2241
- if (isImportant) {
2242
- popsDOMUtils.addClassName(ele, PopsCommonCSSClassName.hideImportant);
2243
- } else {
2244
- popsDOMUtils.addClassName(ele, PopsCommonCSSClassName.hide);
2245
- }
2246
- }
2247
- /**
2248
- * cssHide的反向使用
2249
- * @param ele
2250
- */
2251
- cssShow(ele: Element | null) {
2252
- if (ele == null) {
2253
- return;
2254
- }
2255
- popsDOMUtils.removeClassName(ele, PopsCommonCSSClassName.hide);
2256
- popsDOMUtils.removeClassName(ele, PopsCommonCSSClassName.hideImportant);
2257
- }
2258
- /**
2259
- * 将字符串转为Element元素
2260
- * @param html
2261
- * @param useParser 是否使用DOMParser来生成元素,有些时候通过DOMParser生成的元素有点问题
2262
- * + true 使用DOMPraser来转换字符串
2263
- * + false (默认)创建一个div,里面放入字符串,然后提取firstChild
2264
- * @param isComplete 是否是完整的
2265
- * + true 如果useParser为true,那么返回整个使用DOMParser转换成的Document
2266
- * 如果useParser为false,返回一个DIV元素,DIV元素内包裹着需要转换的字符串
2267
- * + false (默认)如果useParser为true,那么返回整个使用DOMParser转换成的Document的body
2268
- * 如果useParser为false,返回一个DIV元素的firstChild
2269
- * @example
2270
- * // 将字符串转为Element元素
2271
- * DOMUtils.parseHTML("<a href='xxxx'></a>")
2272
- * > <a href="xxxx"></a>
2273
- * @example
2274
- * // 使用DOMParser将字符串转为Element元素
2275
- * DOMUtils.parseHTML("<a href='xxxx'></a>",true)
2276
- * > <a href="xxxx"></a>
2277
- * @example
2278
- * // 由于需要转换的元素是多个元素,将字符串转为完整的Element元素
2279
- * DOMUtils.parseHTML("<a href='xxxx'></a><a href='xxxx'></a>",false, true)
2280
- * > <div><a href="xxxx"></a><a href='xxxx'></a></div>
2281
- * @example
2282
- * // 由于需要转换的元素是多个元素,使用DOMParser将字符串转为完整的Element元素
2283
- * DOMUtils.parseHTML("<a href='xxxx'></a><a href='xxxx'></a>",true, true)
2284
- * > #document
2285
- */
2286
- parseHTML<T1 extends boolean, T2 extends boolean>(
2287
- html: string,
2288
- useParser?: T1,
2289
- isComplete?: T2
2290
- ): ParseHTMLReturnType<T1, T2>;
2291
- parseHTML(html: string, useParser = false, isComplete = false) {
2292
- function parseHTMLByDOMParser() {
2293
- let parser = new DOMParser();
2294
- if (isComplete) {
2295
- return parser.parseFromString(html, "text/html");
2296
- } else {
2297
- return parser.parseFromString(html, "text/html").body.firstChild;
2298
- }
2299
- }
2300
- function parseHTMLByCreateDom() {
2301
- let tempDIV = PopsCore.document.createElement("div");
2302
- PopsSafeUtils.setSafeHTML(tempDIV, html);
2303
- if (isComplete) {
2304
- return tempDIV;
2305
- } else {
2306
- return tempDIV.firstChild;
2307
- }
2308
- }
2309
- if (useParser) {
2310
- return parseHTMLByDOMParser();
2311
- } else {
2312
- return parseHTMLByCreateDom();
2313
- }
2314
- }
2315
-
2316
- /**
2317
- * 函数在元素内部末尾添加子元素或HTML字符串
2318
- * @param element 目标元素
2319
- * @param content 子元素或HTML字符串
2320
- * @example
2321
- * // 元素a.xx的内部末尾添加一个元素
2322
- * DOMUtils.append(document.querySelector("a.xx"),document.querySelector("b.xx"))
2323
- * DOMUtils.append("a.xx","'<b class="xx"></b>")
2324
- * */
2325
- append(
2326
- element: Element | Node | ShadowRoot | HTMLElement | string,
2327
- content:
2328
- | HTMLElement
2329
- | string
2330
- | (HTMLElement | string | Element)[]
2331
- | NodeList
2332
- ) {
2333
- if (typeof element === "string") {
2334
- element = PopsCore.document.querySelector(element) as HTMLElement;
2335
- }
2336
- if (element == null) {
2337
- return;
2338
- }
2339
- function elementAppendChild(ele: HTMLElement, text: HTMLElement | string) {
2340
- if (typeof content === "string") {
2341
- ele.insertAdjacentHTML(
2342
- "beforeend",
2343
- PopsSafeUtils.getSafeHTML(text as string)
2344
- );
2345
- } else {
2346
- ele.appendChild(text as HTMLElement);
2347
- }
2348
- }
2349
- if (Array.isArray(content) || content instanceof NodeList) {
2350
- /* 数组 */
2351
- let fragment = PopsCore.document.createDocumentFragment();
2352
- content.forEach((ele) => {
2353
- if (typeof ele === "string") {
2354
- ele = this.parseHTML(ele, true, false);
2355
- }
2356
- fragment.appendChild(ele);
2357
- });
2358
- element.appendChild(fragment);
2359
- } else {
2360
- elementAppendChild(element as HTMLElement, content);
2361
- }
2362
- }
2363
- /**
2364
- * 把元素标签添加到head内
2365
- */
2366
- appendHead($ele: HTMLElement) {
2367
- if (PopsCore.document.head) {
2368
- PopsCore.document.head.appendChild($ele);
2369
- } else {
2370
- PopsCore.document.documentElement.appendChild($ele);
2371
- }
2372
- }
2373
- /**
2374
- * 把元素添加进body内
2375
- * @param $ele
2376
- */
2377
- appendBody($ele: HTMLElement) {
2378
- if (PopsCore.document.body) {
2379
- PopsCore.document.body.appendChild($ele);
2380
- } else {
2381
- PopsCore.document.documentElement.appendChild($ele);
2382
- }
2383
- }
2384
-
2385
- /**
2386
- * 判断元素是否已显示或已连接
2387
- * @param element
2388
- */
2389
- isShow(element: HTMLElement) {
2390
- return Boolean(element.getClientRects().length);
2391
- }
2392
- /**
2393
- * 用于显示元素并获取它的高度宽度等其它属性
2394
- * @param $ele
2395
- * @param parent 父元素
2396
- */
2397
- showElement($ele: HTMLElement, ownParent?: Node) {
2398
- /** 克隆元素 */
2399
- let $cloneNode = $ele.cloneNode(true) as HTMLElement;
2400
- $cloneNode.setAttribute(
2401
- "style",
2402
- "visibility: hidden !important;display:block !important;"
2403
- );
2404
- let $parent: Node = PopsCore.document.documentElement;
2405
- // 这里需要的是先获取元素的父节点,把元素同样添加到父节点中
2406
- let $root = $ele.getRootNode();
2407
- if (ownParent == null) {
2408
- if ($root == $ele) {
2409
- // 未添加到任意节点中,那么直接添加到页面中去
2410
- $parent = PopsCore.document.documentElement;
2411
- } else {
2412
- // 添加到父节点中
2413
- $parent = $root;
2414
- }
2415
- } else {
2416
- // 自定义的父节点
2417
- $parent = ownParent;
2418
- }
2419
- $parent.appendChild($cloneNode);
2420
- return {
2421
- /**
2422
- * 强制显示的克隆的元素
2423
- */
2424
- cloneNode: $cloneNode,
2425
- /**
2426
- * 恢复修改的style
2427
- */
2428
- recovery() {
2429
- $cloneNode.remove();
2430
- },
2431
- };
2432
- }
2433
- /**
2434
- * 获取元素上的Float格式的属性px
2435
- * @param element
2436
- * @param styleName style名
2437
- */
2438
- getStyleValue(element: HTMLElement | CSSStyleDeclaration, styleName: string) {
2439
- let view = null;
2440
- let styles = null;
2441
- if (element instanceof CSSStyleDeclaration) {
2442
- /* 直接就获取了style属性 */
2443
- styles = element;
2444
- } else {
2445
- view = element.ownerDocument.defaultView;
2446
- if (!view || !view.opener) {
2447
- view = window;
2448
- }
2449
- styles = view.getComputedStyle(element);
2450
- }
2451
- let value = parseFloat(styles[styleName as any]);
2452
- if (isNaN(value)) {
2453
- return 0;
2454
- } else {
2455
- return value;
2456
- }
2457
- }
2458
- /**
2459
- * 在元素前面添加兄弟元素或HTML字符串
2460
- * @param element 目标元素
2461
- * @param content 兄弟元素或HTML字符串
2462
- * @example
2463
- * // 元素a.xx前面添加一个元素
2464
- * DOMUtils.before(document.querySelector("a.xx"),document.querySelector("b.xx"))
2465
- * DOMUtils.before("a.xx","'<b class="xx"></b>")
2466
- * */
2467
- before(
2468
- element: HTMLElement | Element | string,
2469
- content: HTMLElement | string
2470
- ) {
2471
- if (typeof element === "string") {
2472
- element = PopsCore.document.querySelector(element) as HTMLElement;
2473
- }
2474
- if (element == null) {
2475
- return;
2476
- }
2477
- if (typeof content === "string") {
2478
- element.insertAdjacentHTML(
2479
- "beforebegin",
2480
- PopsSafeUtils.getSafeHTML(content)
2481
- );
2482
- } else {
2483
- element!.parentElement!.insertBefore(content, element);
2484
- }
2485
- }
2486
- /**
2487
- * 在元素后面添加兄弟元素或HTML字符串
2488
- * @param element 目标元素
2489
- * @param content 兄弟元素或HTML字符串
2490
- * @example
2491
- * // 元素a.xx后面添加一个元素
2492
- * DOMUtils.after(document.querySelector("a.xx"),document.querySelector("b.xx"))
2493
- * DOMUtils.after("a.xx","'<b class="xx"></b>")
2494
- * */
2495
- after(
2496
- element: HTMLElement | Element | string,
2497
- content: HTMLElement | string
2498
- ) {
2499
- if (typeof element === "string") {
2500
- element = PopsCore.document.querySelector(element) as HTMLElement;
2501
- }
2502
- if (element == null) {
2503
- return;
2504
- }
2505
- if (typeof content === "string") {
2506
- element.insertAdjacentHTML(
2507
- "afterend",
2508
- PopsSafeUtils.getSafeHTML(content)
2509
- );
2510
- } else {
2511
- element!.parentElement!.insertBefore(content, element.nextSibling);
2512
- }
2513
- }
2514
- /**
2515
- * 获取CSS Rule
2516
- * @param sheet
2517
- * @returns
2518
- */
2519
- getKeyFrames(sheet: CSSStyleSheet) {
2520
- let result = {};
2521
- Object.keys(sheet.cssRules).forEach((key) => {
2522
- if (
2523
- (sheet.cssRules as any)[key].type === 7 &&
2524
- (sheet.cssRules as any)[key].name.startsWith("pops-anim-")
2525
- ) {
2526
- (result as any)[(sheet.cssRules as any)[key].name] = (
2527
- sheet.cssRules as any
2528
- )[key];
2529
- }
2530
- });
2531
- return result;
2532
- }
2533
- /**
2534
- * 颜色转换函数
2535
- * @method hexToRgb hex 颜色转 rgb 颜色
2536
- * @method rgbToHex rgb 颜色转 Hex 颜色
2537
- * @method getDarkColor 加深颜色值
2538
- * @method getLightColor 变浅颜色值
2539
- */
2540
- calcColor() {
2541
- function useChangeColor() {
2542
- /**
2543
- * hex 颜色转 rgb 颜色
2544
- */
2545
- const hexToRgb = (
2546
- /**
2547
- * hex 颜色值
2548
- */
2549
- str: string
2550
- ): any => {
2551
- let hexs: any = "";
2552
- let reg = /^#(?:[0-9A-Fa-f]{3}|[0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$/;
2553
- if (!reg.test(str)) {
2554
- console.warn("输入错误的hex");
2555
- return "";
2556
- }
2557
- str = str.replace("#", "");
2558
- hexs = str.match(/../g);
2559
- for (let i = 0; i < 3; i++) hexs[i] = parseInt(hexs[i], 16);
2560
- return hexs;
2561
- };
2562
-
2563
- /**
2564
- * rgb转hex
2565
- */
2566
- const rgbToHex = (
2567
- /**
2568
- * 红色
2569
- */
2570
- r: any,
2571
- /**
2572
- * 绿色
2573
- */
2574
- g: any,
2575
- /**
2576
- * 蓝色
2577
- */
2578
- b: any
2579
- ): string => {
2580
- let reg = /^\d{1,3}$/;
2581
- if (!reg.test(r) || !reg.test(g) || !reg.test(b)) {
2582
- console.warn("输入错误的rgb颜色值");
2583
- return "";
2584
- }
2585
- let hexs = [r.toString(16), g.toString(16), b.toString(16)];
2586
- for (let i = 0; i < 3; i++)
2587
- if (hexs[i].length == 1) hexs[i] = `0${hexs[i]}`;
2588
- return `#${hexs.join("")}`;
2589
- };
2590
-
2591
- /**
2592
- * 获取深色
2593
- */
2594
- const getDarkColor = (
2595
- /**
2596
- * 颜色值字符串
2597
- */
2598
- color: string,
2599
- /**
2600
- * 加深的程度,限0-1之间
2601
- */
2602
- level: number
2603
- ): string => {
2604
- let reg = /^#(?:[0-9A-Fa-f]{3}|[0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$/;
2605
- if (!reg.test(color)) {
2606
- console.warn("输入错误的hex颜色值");
2607
- return "";
2608
- }
2609
- let rgb = useChangeColor().hexToRgb(color);
2610
- for (let i = 0; i < 3; i++) rgb[i] = Math.floor(rgb[i] * (1 - level));
2611
- return useChangeColor().rgbToHex(rgb[0], rgb[1], rgb[2]);
2612
- };
2613
-
2614
- /**
2615
- * 获取颜色变浅后的颜色值
2616
- */
2617
- const getLightColor = (
2618
- /**
2619
- * 颜色值字符串
2620
- */
2621
- color: string,
2622
- /**
2623
- * 加深的程度,限0-1之间
2624
- */
2625
- level: number
2626
- ): string => {
2627
- let reg = /^#(?:[0-9A-Fa-f]{3}|[0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$/;
2628
- if (!reg.test(color)) {
2629
- console.warn("输入错误的hex颜色值");
2630
- return "";
2631
- }
2632
- let rgb = useChangeColor().hexToRgb(color);
2633
- for (let i = 0; i < 3; i++)
2634
- rgb[i] = Math.floor((255 - rgb[i]) * level + rgb[i]);
2635
- return useChangeColor().rgbToHex(rgb[0], rgb[1], rgb[2]);
2636
- };
2637
- return {
2638
- hexToRgb,
2639
- rgbToHex,
2640
- getDarkColor,
2641
- getLightColor,
2642
- };
2643
- }
2644
- return useChangeColor();
2645
- }
2646
- }
2647
-
2648
- const popsDOMUtils = new PopsDOMUtils();
2649
- export { popsDOMUtils };