ph-utils 0.17.2 → 0.19.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.
@@ -0,0 +1,202 @@
1
+ /**
2
+ * node 和 web 端日期处理工具类
3
+ */
4
+ // 配置日期格式的正则表达式
5
+ const REGEX_FORMAT = /yy(?:yy)?|([HMmds])\1?|(S)?/g;
6
+ // 由于 Date.parse() 不能正确解析 yyyy-dd-mm 格式的日期, 所以匹配手动解析
7
+ const REGEX_PARSE = /^(\d{4})-?(\d{1,2})-?(\d{0,2})[^0-9]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?.?(\d{1,3})?$/;
8
+ const ofArgs = {
9
+ start: [0, 0, 1, 0, 0, 0, 0],
10
+ end: [0, 11, -2, 23, 59, 59, 999],
11
+ };
12
+ const units = {
13
+ Date: ["date", "Date", "day", "Day", "D", "d"],
14
+ Month: ["Month", "month", "m"],
15
+ FullYear: ["Year", "year", "y"],
16
+ Hours: ["Hours", "hours", "H"],
17
+ Minutes: ["Minutes", "Minute", "minute", "minutes", "M"],
18
+ Seconds: ["Seconds", "seconds", "Second", "second", "s"],
19
+ Milliseconds: ["Milliseconds", "Millisecond", "milliseconds", "illisecond", "S"],
20
+ };
21
+ /**
22
+ * 不足位数, 前位补 0
23
+ * @param s 日期数字
24
+ * @param l 截取位数
25
+ * @returns {string} 补0后的日期数字
26
+ */
27
+ function p(s, l = 2) {
28
+ /*
29
+ * 由于年份最多为4为,所以前面先添3个0
30
+ * slice() 从后开始提前字符串
31
+ */
32
+ return `000${s}`.slice(l * -1);
33
+ }
34
+ /**
35
+ * 将单位转换为首字母大写, 例如:hours -> Hours
36
+ * @param unit hours
37
+ * @returns
38
+ */
39
+ function getUnit(unit) {
40
+ let period = null;
41
+ for (const [key, value] of Object.entries(units)) {
42
+ if (value.includes(unit)) {
43
+ period = key;
44
+ break;
45
+ }
46
+ }
47
+ if (period == null) {
48
+ throw new Error(`Invalid unit: ${unit}`);
49
+ }
50
+ return period;
51
+ }
52
+ /**
53
+ * 获取指定日期某个月的最后一天
54
+ * @param date 日期
55
+ * @param month 月份, 如果不传, 则当前月的最后一天
56
+ * @returns
57
+ */
58
+ function getLastDayOfMonth(date, month) {
59
+ // 获取下个月的第一天
60
+ const lastDate = new Date(date.getFullYear(), (month || date.getMonth()) + 1, 1);
61
+ // 将下个月的第一天的日期减去一天,得到当前月的最后一天
62
+ lastDate.setDate(lastDate.getDate() - 1);
63
+ // 返回最后一天的日期
64
+ return lastDate.getDate();
65
+ }
66
+ /**
67
+ * 将日期格式化为指定形式的字符串
68
+ * @param date 日期
69
+ * @param pattern 格式化字符串 yyyy - 年, mm - 月, dd - 日, HH - 小时(24时制), MM - 分钟, ss - 秒, S - 毫秒, 默认: yyyy-mm-dd HH:MM:ss
70
+ */
71
+ export function format(date, pattern = "yyyy-mm-dd HH:MM:ss") {
72
+ // eslint-disable-next-line
73
+ date = parse(date);
74
+ const d = date.getDate();
75
+ const y = date.getFullYear();
76
+ const m = date.getMonth();
77
+ const H = date.getHours();
78
+ const M = date.getMinutes();
79
+ const s = date.getSeconds();
80
+ const flags = {
81
+ yy: p(y),
82
+ yyyy: y,
83
+ m: m + 1,
84
+ mm: p(m + 1),
85
+ d: d,
86
+ dd: p(d),
87
+ H: H,
88
+ HH: p(H),
89
+ M: M,
90
+ MM: p(M),
91
+ s: s,
92
+ ss: p(s),
93
+ S: p(date.getMilliseconds(), 3),
94
+ };
95
+ if (pattern != null) {
96
+ return pattern.replace(REGEX_FORMAT, (flag) => {
97
+ if (flag in flags) {
98
+ return flags[flag];
99
+ }
100
+ return flag;
101
+ });
102
+ }
103
+ return String(date.getTime());
104
+ }
105
+ /**
106
+ * 将指定的参数解析为日期对象(Date)
107
+ * 参考 dayjs 实现, 也可以参考 https://github.com/nomiddlename/date-format
108
+ * @param date 待解析的日期参数
109
+ */
110
+ export function parse(date) {
111
+ if (date == null)
112
+ return new Date();
113
+ if (typeof date === "string" && !/Z$/i.test(date)) {
114
+ const d = date.match(REGEX_PARSE);
115
+ if (d) {
116
+ return new Date(d[1], d[2] - 1, d[3] || 1, d[4] || 0, d[5] || 0, d[6] || 0, d[7] || 0);
117
+ }
118
+ }
119
+ if (typeof date === "number") {
120
+ return new Date(date <= 9999999999 ? date * 1000 : date);
121
+ }
122
+ return new Date(date);
123
+ }
124
+ /**
125
+ * 设置日期的开始或者结束的点
126
+ * @param date 日期,能够被 parse 解析的日期
127
+ * @param unit 单位,Date[D]、Minute[M], 默认为 Date
128
+ * @param isEnd true则为 endOf
129
+ */
130
+ export function dateOf(date, unit, isEnd = false) {
131
+ /* 如果是设置某一天的开始时刻, 就需要将时、分、秒、毫秒设置为0,依次类推设置 */
132
+ const periods = ["Year", "Month", "Date", "Hours", "Minutes", "Seconds", "Milliseconds"];
133
+ let index = periods.indexOf(getUnit(unit || "Date"));
134
+ const clone = parse(date);
135
+ index++;
136
+ const setValues = ofArgs[isEnd === true ? "end" : "start"];
137
+ for (const len = periods.length; index < len; index++) {
138
+ let value = setValues[index];
139
+ if (value === -2) {
140
+ // 设置为某个月的最后一天的日期
141
+ value = getLastDayOfMonth(clone);
142
+ }
143
+ Date.prototype["set" + periods[index]].apply(clone, [setValues[index]]);
144
+ }
145
+ return clone;
146
+ }
147
+ /**
148
+ * 设置日期的开始的点
149
+ * @param date 日期,能够被 parse 解析的日期
150
+ * @param unit 单位,Date[D]、Minute[M], 默认为 Date
151
+ * @returns
152
+ */
153
+ export function startOf(date, unit) {
154
+ return dateOf(date, unit);
155
+ }
156
+ /**
157
+ * 设置日期的结束点
158
+ * @param date 日期,能够被 parse 解析的日期
159
+ * @param unit 单位,Date[D]、Minute[M], 默认为 Date
160
+ * @returns
161
+ */
162
+ export function endOf(date, unit) {
163
+ return dateOf(date, unit, true);
164
+ }
165
+ /**
166
+ * 获取时间戳
167
+ * @param ctime 时间
168
+ * @param pre 精度, s - 精确到秒, ms - 精确到毫秒, 默认: s
169
+ * @returns
170
+ */
171
+ export function timestamp(ctime, pre = "s") {
172
+ let tm = parse(ctime).getTime();
173
+ return pre === "s" ? Math.floor(tm / 1000) : tm;
174
+ }
175
+ /**
176
+ * 日期加上指定时间后的日期
177
+ * @param date 指定的日期
178
+ * @param num 需要添加的数字, 如果这个参数传递一个小于0的数字,则就是日期减去相应的数字
179
+ * @param unit 需要添加的单位,date - 加减天数
180
+ * @param fmt 可选参数,如果传递了格式化的单位,则返回格式化后的日期, 格式化字符串 yyyy - 年, mm - 月, dd - 日, HH - 小时, MM - 分钟, ss - 秒
181
+ * @returns {Date | string} 如果传递了 fmt 参数,则返回 string,否则返回 Date
182
+ */
183
+ export function add(date, num, unit, fmt) {
184
+ let sdate = new Date();
185
+ if (date != null) {
186
+ sdate = parse(date);
187
+ }
188
+ // eslint-disable-next-line
189
+ unit = getUnit(unit);
190
+ let fn = "set" + unit;
191
+ let gn = "get" + unit;
192
+ // @ts-ignore
193
+ let oldValue = Date.prototype[gn].apply(sdate);
194
+ // @ts-ignore
195
+ Date.prototype[fn].apply(sdate, [oldValue + num]);
196
+ if (typeof fmt === "string") {
197
+ return format(sdate, fmt);
198
+ }
199
+ else {
200
+ return sdate;
201
+ }
202
+ }
@@ -0,0 +1,265 @@
1
+ /**
2
+ * web(浏览器端) DOM 文件操作
3
+ * 现今不推荐在使用这种方式,现在开发前端的时候,推荐使用一些成熟的框架例如:React、Preact、Vue、Angular、Svelte、Ember、Knockout等
4
+ * 在使用这些框架的时候额外的一些不可避免的 dom 操作时才使用这个工具;如果确实需要使用原生开发推荐使用 jquery 或者想要更精简的话可以使用 https://github.com/finom/bala 封装
5
+ */
6
+ /**
7
+ * 根据选择器获取节点
8
+ * @param {string} selector 选择器
9
+ */
10
+ type FormatStyleParam = (string | undefined | null)[] | Record<string, boolean | string | undefined | null> | string;
11
+ type FormatClassParam = (string | undefined | null | boolean)[] | Record<string, boolean | string | undefined | null | boolean> | string;
12
+ type DocumentContext = HTMLElement | ShadowRoot | Document;
13
+ type NodeChildren = HTMLElement | DocumentFragment | HTMLElement[] | NodeListOf<HTMLElement> | HTMLCollection;
14
+ export declare function elem(selector: string | HTMLElement, dom?: DocumentContext): HTMLElement[];
15
+ /**
16
+ * 根据选择器获取 DOM 元素。
17
+ * @param selector - 选择器字符串或 HTMLElement 实例。
18
+ * @param dom - 可选参数,指定在哪个 DOM 节点下查找元素,默认为 document。
19
+ * @returns 返回匹配到的 HTMLElement 实例。
20
+ */
21
+ export declare function $(selector: string | HTMLElement, dom?: DocumentContext): HTMLElement[];
22
+ /**
23
+ * 创建一个 HTML 元素,支持通过标签名或 HTML 字符串创建。
24
+ * @param tag - 元素标签名或 HTML 字符串。
25
+ * @param option - 元素的属性、样式、文本内容等配置。所有不是指定的属性,都会通过 setAttribute 设置
26
+ * @param ctx - 元素的父级文档上下文。
27
+ * @returns 创建的 HTML 元素。
28
+ */
29
+ export declare function create(tag: string, option?: {
30
+ class?: FormatClassParam;
31
+ style?: FormatStyleParam;
32
+ textContent?: string;
33
+ innerHTML?: string;
34
+ outerHTML?: string;
35
+ [index: string]: any;
36
+ }, children?: NodeChildren): HTMLElement;
37
+ /** 创建节点 */
38
+ export declare function $$(tag: string, option?: {
39
+ class?: FormatClassParam;
40
+ style?: FormatStyleParam;
41
+ textContent?: string;
42
+ innerHTML?: string;
43
+ outerHTML?: string;
44
+ [index: string]: any;
45
+ }, children?: NodeChildren): HTMLElement;
46
+ /**
47
+ * 根据选择器获取匹配的第一个 DOM 元素。
48
+ * @param selector - 选择器字符串或直接的 HTMLElement。
49
+ * @param dom - 可选的父级 DOM 元素,默认为当前文档。
50
+ * @returns 返回匹配的第一个 HTMLElement,如果没有找到则返回 null。
51
+ */
52
+ export declare function $one(selector: string | HTMLElement, dom?: DocumentContext): HTMLElement | null;
53
+ /**
54
+ * 为节点添加 class
55
+ * @param {HTMLElement} elem 待添加 class 的节点
56
+ * @param {string} clazz 需要添加的 class
57
+ */
58
+ export declare function addClass(elem: HTMLElement, clazz: string): void;
59
+ /**
60
+ * 节点移除 class
61
+ * @param {HTMLElement} elem 待移除 class 的节点
62
+ * @param {string} clazz 需要移除的 class
63
+ */
64
+ export declare function removeClass(elem: HTMLElement, clazz: string): void;
65
+ /**
66
+ * 判断节点是否包含某个 class
67
+ * @param elem 待判断 class 的节点
68
+ * @param clazz 待判断的 class
69
+ * @returns
70
+ */
71
+ export declare function hasClass(elem: HTMLElement, clazz: string): boolean;
72
+ /**
73
+ * 切换指定元素的类名。
74
+ * 如果元素已包含该类名,则移除它;否则添加它。
75
+ * @param el - 要操作的 HTML 元素。
76
+ * @param clazz - 要切换的类名。
77
+ */
78
+ export declare function toggleClass(el: HTMLElement, clazz: string): void;
79
+ /**
80
+ * 替换指定元素的 CSS 类
81
+ *
82
+ * 该函数用于根据给定的旧类名或类索引,将其替换为新类名。
83
+ * 如果旧类不存在,则不会进行替换。
84
+ *
85
+ * @param el - 目标 HTML 元素,将对其类进行操作
86
+ * @param oldClazz - 要替换的旧类名或类索引(基于数字时对应 classList 的索引位置)
87
+ * @param newClazz - 新的类名,用于替换旧的类
88
+ * @returns void
89
+ */
90
+ export declare function replaceClass(el: HTMLElement, oldClazz: string | number, newClazz: string): void;
91
+ type EventHandler = EventListenerOrEventListenerObject | ((e: CustomEvent) => void);
92
+ /**
93
+ * 为节点添加事件处理
94
+ * @param {HTMLElement} element 添加事件的节点
95
+ * @param {string} listener 事件名称
96
+ * @param {function} fn 事件处理函数
97
+ * @param {boolean} option 是否是只运行一次的处理函数或者配置,其中 eventFlag 为 string,如果配置该项,则表明为委托事件
98
+ */
99
+ export declare function on(element: HTMLElement | ShadowRoot | Document | HTMLCollection | NodeListOf<HTMLElement> | HTMLElement[], listener: string, fn: EventHandler, option?: boolean | (AddEventListenerOptions & {
100
+ eventFlag?: string;
101
+ })): void;
102
+ /**
103
+ * 移除指定元素的事件监听器。
104
+ * @param el - 要移除监听器的 HTML 元素。
105
+ * @param listener - 事件名称。
106
+ * @param fn - 要移除的事件监听器函数。
107
+ */
108
+ export declare function off(el: HTMLElement | ShadowRoot | Document | HTMLCollection | NodeListOf<HTMLElement> | HTMLElement[], listener: string, fn: EventHandler, option?: boolean | EventListenerOptions): void;
109
+ /**
110
+ * 判断事件是否应该继续传递。
111
+ * 从事件目标开始向上遍历DOM树,检查每个节点上是否存在指定的属性。
112
+ * 如果找到该属性且其值不为'__stop__',则返回true,表示事件可以继续传递。
113
+ * 否则,返回false,表示事件应该停止传递。
114
+ * 通常用于事件委托时判断是否继续传递事件。
115
+ *
116
+ * @param e - 触发的事件对象
117
+ * @param eventFlag - 需要检查的属性名
118
+ * @param endRoot - 可选,如果传递该参数,则表示停止遍历的节点,如果未传递,则表示遍历到文档根节点为止
119
+ * @returns 包含三个元素的数组:[是否继续传递事件, 属性值, 当前检查的DOM节点]
120
+ */
121
+ export declare function shouldEventNext(e: Event, eventFlag: string, endRoot?: HTMLElement | ShadowRoot): [boolean, string, HTMLElement];
122
+ /**
123
+ * 设置或获取节点的 innerHTML 属性
124
+ * @param element
125
+ * @param htmlstr 可选,如果传递该参数,则表示设置;否则表示获取
126
+ * @returns
127
+ */
128
+ export declare function html(element: HTMLElement, htmlstr?: string): string | undefined;
129
+ /**
130
+ * 设置或获取节点的 textContent 属性
131
+ * @param element
132
+ * @param textstr 可选,如果传递该参数,则表示设置;否则表示获取
133
+ * @returns
134
+ */
135
+ export declare function text(element: HTMLElement, textstr?: string): string | undefined | null;
136
+ export declare function iterate<T>(elems: T[], fn: (el: T, index: number) => any): void;
137
+ export declare function iterate(elems: NodeList | HTMLCollection | NodeListOf<HTMLElement>, fn: (el: HTMLElement, index: number) => any): void;
138
+ /**
139
+ * 设置或获取节点 data-* 属性
140
+ * @param elem
141
+ * @param key data- 后面跟随的值
142
+ * @param value 如果传递该值表示获取;否则表示设置
143
+ * @returns
144
+ */
145
+ export declare function attr(elem: HTMLElement, key: string, value?: string): string | null | undefined;
146
+ /**
147
+ * 获取属性值
148
+ * @param key 属性名称
149
+ */
150
+ export declare function getAttr(el: HTMLElement, key: string): string;
151
+ /**
152
+ * 获取属性值,同时将值转换为默认值的类型,如果未赋值,则返回默认值;
153
+ * @param key 属性名称
154
+ * @param defaultValue 默认值
155
+ */
156
+ export declare function getAttr(el: HTMLElement, filepath: string, defaultValue: string): string;
157
+ export declare function getAttr(el: HTMLElement, filepath: string, defaultValue: number): number;
158
+ export declare function getAttr(el: HTMLElement, filepath: string, defaultValue: boolean): boolean;
159
+ export declare function getAttr<T extends Record<string, string | number | boolean>>(el: HTMLElement, filepath: string, defaultValue: T): T;
160
+ /**
161
+ * 获取指定节点的父节点
162
+ * @param el
163
+ * @returns
164
+ */
165
+ export declare function parent(el: HTMLElement): HTMLElement;
166
+ /**
167
+ * 获取隐藏节点的尺寸, 如果 parent 传空, 且 hideNode 为节点,则会通过修改原始样式方式计算
168
+ * @param {string | HTMLElement} hideNode - The node to hide.
169
+ * @param parent - 添加临时节点的父节点, 如果传递 null, 则通过修改原始样式方式计算,默认为: body.
170
+ * @returns The DOMRect of the element.
171
+ */
172
+ export declare function queryHideNodeSize(hideNode: string | HTMLElement, parent?: null | HTMLElement): {
173
+ width: number;
174
+ height: number;
175
+ };
176
+ /**
177
+ * 判断元素是否在父元素的可视区域内。
178
+ *
179
+ * @param el 要检查的元素
180
+ * @param parent 元素的父元素,默认为document.body
181
+ * @param direction 检查的方向,默认为"horizontal"
182
+ * @returns 如果元素在父元素的可视区域内,则返回true;否则返回false。
183
+ */
184
+ export declare function isVisible(el: HTMLElement, parent?: HTMLElement | null | undefined, direction?: string): boolean;
185
+ /**
186
+ * 判断当前设备是否为移动设备。
187
+ *
188
+ * 本函数通过检查用户代理字符串和屏幕尺寸来判断设备是否为移动设备。
189
+ * 这对于需要根据设备类型进行不同布局或功能调整的应用非常有用。
190
+ *
191
+ * @returns {boolean} 如果设备是移动设备,则返回true;否则返回false。
192
+ */
193
+ export declare function isMobile(): boolean;
194
+ /**
195
+ * 格式化类名,支持数组和对象两种形式。
196
+ * - 数组形式:数组中的每个元素代表一个类名,非空元素将被添加到结果字符串中。
197
+ * - 对象形式:对象的键代表类名,值为真(非空、非undefined、非null)时,键将被添加到结果字符串中。
198
+ * @param classObj - 类名对象或数组
199
+ * @returns 格式化后的类名字符串
200
+ */
201
+ export declare function formatClass(classObj: (boolean | string | undefined | null)[] | Record<string, boolean | string | undefined | null> | string): string;
202
+ /**
203
+ * 将样式对象格式化为 CSS 样式字符串。
204
+ * @param styleObj - 样式对象,可以是字符串数组或键值对对象。
205
+ * @returns 格式化后的 CSS 样式字符串。
206
+ */
207
+ export declare function formatStyle(styleObj: FormatStyleParam): string;
208
+ /**
209
+ * 执行元素的过渡动画。
210
+ *
211
+ * 如果是名称类似于 Vue.js 的过渡动画,通过添加 `*-active`、`*-from|to` class 类名。
212
+ *
213
+ * @param el - 需要执行过渡动画的 HTML 元素。
214
+ * @param nameOrProperties - 过渡动画的名称或属性数组。可以是字符串表示的动画名称,或者是包含属性名称、初始值或目标值、持续时间。eg. [['opacity', '0.5']] | 'nt-opacity'
215
+ * @param dir - 过渡动画的方向,"leave" 表示离开,"enter" 表示进入。默认值为 "enter"。
216
+ * @param finish - 过渡动画结束时的回调函数。
217
+ *
218
+ * @example <caption>执行 `nt-opacity` 名称动画</caption>
219
+ * // css
220
+ * .nt-opacity-enter-active,
221
+ * .nt-opacity-leave-active {
222
+ * transition: opacity 0.3s ease;
223
+ * }
224
+ * .nt-opacity-enter-from,
225
+ * .nt-opacity-leave-to {
226
+ * opacity: 0;
227
+ * }
228
+ * // js
229
+ * transition($el, "nt-opacity", "enter");
230
+ *
231
+ * @example <caption>执行 `style` 属性动画</caption>
232
+ * transition($el, [["opacity", "0", "0.3s"]], "enter");
233
+ *
234
+ * @example <caption>动画结束后移除节点</caption>
235
+ * transition($el, [["opacity", "0", "0.3s"]], "leave", () => { $el.remove(); });
236
+ */
237
+ export declare function transition(el: HTMLElement, nameOrProperties: string | [string, string, string][], dir?: "leave" | "enter", finish?: () => void): void;
238
+ /**
239
+ * 计算光标位置
240
+ *
241
+ * 根据输入值的变化计算新的光标位置,主要用于输入框内容变化时的光标位置调整
242
+ *
243
+ * @param start - 光标起始位置,通常为: input.selectionStart
244
+ * @param end - 光标结束位置(通常与起始位置相同,用于选择范围),通常为: input.selectionEnd
245
+ * @param oldValue - 变化前的值
246
+ * @param newValue - 变化后的值
247
+ * @returns 新的光标位置对象,包含新的起始和结束位置
248
+ *
249
+ * @example
250
+ * // 删除字符时,光标向前移动
251
+ * calcuteCursorPosition(2, 2, "abc", "ac"); // 返回 { start: 1, end: 1 }
252
+ *
253
+ * @example
254
+ * // 添加字符时,光标向后移动
255
+ * calcuteCursorPosition(2, 2, "ac", "abc"); // 返回 { start: 3, end: 3 }
256
+ *
257
+ * @example
258
+ * // 替换字符时,保持位置
259
+ * calcuteCursorPosition(2, 2, "abc", "axc"); // 返回 { start: 2, end: 2 }
260
+ */
261
+ export declare function calcuteCursorPosition(start: number, end: number, oldValue: string, newValue: string): {
262
+ start: number;
263
+ end: number;
264
+ };
265
+ export {};