ph-utils 0.2.23 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/dom.js CHANGED
@@ -1,190 +1,190 @@
1
- /**
2
- * web(浏览器端) DOM 文件操作
3
- * 现今不推荐在使用这种方式,现在开发前端的时候,推荐使用一些成熟的框架例如:React、Preact、Vue、Angular、Svelte、Ember、Knockout等
4
- * 在使用这些框架的时候额外的一些不可避免的 dom 操作时才使用这个工具;如果确实需要使用原生开发推荐使用 jquery 或者想要更精简的话可以使用 https://github.com/finom/bala 封装
5
- */
6
- const vendorPrefix = ['', '-webkit', '-moz-'];
7
- /**
8
- * 根据选择器获取节点
9
- * @param {string} selector 选择器
10
- */
11
- export function elem(selector, dom) {
12
- if (typeof selector === 'string') {
13
- return (dom || document).querySelectorAll(selector);
14
- }
15
- else {
16
- return [selector];
17
- }
18
- }
19
- /**
20
- * 为节点添加 class
21
- * @param {HTMLElement} elem 待添加 class 的节点
22
- * @param {string} clazz 需要添加的 class
23
- */
24
- export function addClass(elem, clazz) {
25
- elem.classList.add(clazz);
26
- }
27
- /**
28
- * 节点移除 class
29
- * @param {HTMLElement} elem 待移除 class 的节点
30
- * @param {string} clazz 需要移除的 class
31
- */
32
- export function removeClass(elem, clazz) {
33
- elem.classList.remove(clazz);
34
- }
35
- /**
36
- * 判断节点是否包含某个 class
37
- * @param elem 待判断 class 的节点
38
- * @param clazz 待判断的 class
39
- * @returns
40
- */
41
- export function hasClass(elem, clazz) {
42
- return elem.classList.contains(clazz);
43
- }
44
- /**
45
- * 为节点添加 transition 属性,包括浏览器前缀
46
- * @param {HTMLElement} element 需要添加 css Transition 属性的节点
47
- * @param {string} value css transition 值
48
- */
49
- export function transition(element, value) {
50
- vendorPrefix.forEach((prefix) => {
51
- let t = prefix === '' ? 'transition' : prefix + 'Transition';
52
- element.style[t] = value;
53
- });
54
- }
55
- /**
56
- * 为节点添加 transform 属性,包括浏览器前缀
57
- * @param {HTMLElement} element 需要添加 css transform 属性的节点
58
- * @param {string} value css transform 值
59
- */
60
- export function transform(element, value) {
61
- vendorPrefix.forEach((prefix) => {
62
- let t = prefix === '' ? 'transform' : prefix + 'Transform';
63
- element.style[t] = value;
64
- });
65
- }
66
- /**
67
- * 为节点添加事件处理
68
- * @param {HTMLElement} element 添加事件的节点
69
- * @param {string} listener 事件名称
70
- * @param {function} event 事件处理函数
71
- * @param {boolean} onceOrConfig 是否是只运行一次的处理函数或者配置,其中 eventFlag 为 string,如果配置该项,则表明为委托事件
72
- */
73
- export function on(element, listener, fn, once = false) {
74
- let eventExtra = { eventStop: false };
75
- if (typeof once === 'boolean') {
76
- eventExtra.once = once;
77
- }
78
- else {
79
- eventExtra = once;
80
- }
81
- if (eventExtra.eventFlag != null) {
82
- element.setAttribute(eventExtra.eventFlag, '__stop__');
83
- element.addEventListener(listener, (e) => {
84
- let target = e.target;
85
- let flag = '';
86
- do {
87
- flag = target.getAttribute(eventExtra.eventFlag) || '';
88
- if (flag === '') {
89
- target = target.parentNode;
90
- }
91
- } while (flag === '');
92
- if (flag !== '__stop__' || eventExtra.eventStop) {
93
- fn(e, target, flag);
94
- }
95
- }, eventExtra);
96
- }
97
- else {
98
- element.addEventListener(listener, fn, eventExtra);
99
- }
100
- }
101
- /**
102
- * 设置或获取节点的 innerHTML 属性
103
- * @param element
104
- * @param htmlstr 可选,如果传递该参数,则表示设置;否则表示获取
105
- * @returns
106
- */
107
- export function html(element, htmlstr) {
108
- if (htmlstr == null) {
109
- return element.innerHTML;
110
- }
111
- else {
112
- element.innerHTML = htmlstr;
113
- return undefined;
114
- }
115
- }
116
- /**
117
- * 设置或获取节点的 textContent 属性
118
- * @param element
119
- * @param textstr 可选,如果传递该参数,则表示设置;否则表示获取
120
- * @returns
121
- */
122
- export function text(element, textstr) {
123
- if (textstr == null) {
124
- return element.textContent;
125
- }
126
- else {
127
- element.textContent = textstr;
128
- return undefined;
129
- }
130
- }
131
- /**
132
- * 节点列表遍历
133
- * @param elems
134
- * @param fn 遍历到节点时的回调,回调第一个参数为遍历到的节点,第2个参数为 index;如果回调函数返回 true,则会终止遍历(break)
135
- */
136
- export function iterate(elems, fn) {
137
- for (let i = 0, len = elems.length; i < len; i++) {
138
- let r = fn(elems[i], i);
139
- if (r === true) {
140
- break;
141
- }
142
- }
143
- }
144
- /**
145
- * 设置或获取节点 data-* 属性
146
- * @param elem
147
- * @param key data- 后面跟随的值
148
- * @param value 如果传递该值表示获取;否则表示设置
149
- * @returns
150
- */
151
- export function attr(elem, key, value) {
152
- if (value != null) {
153
- elem.setAttribute('data-' + key, value);
154
- }
155
- else {
156
- return elem.getAttribute('data-' + key);
157
- }
158
- }
159
- /**
160
- * 获取指定节点的父节点
161
- * @param el
162
- * @returns
163
- */
164
- export function parent(el) {
165
- return el.parentNode;
166
- }
167
- /**
168
- * 获取隐藏节点的尺寸
169
- * @param {string | HTMLElement} hideNode - The node to hide.
170
- * @param parent - 添加临时节点的父节点,默认为: body.
171
- * @returns The DOMRect of the element.
172
- */
173
- export function queryHideNodeSize(hideNode, parent = document.body) {
174
- // 计算折叠菜单的高度
175
- let $tmp = document.createElement('div');
176
- $tmp.style.cssText = 'position:fixed;left:-1000px;top:-1000px;opacity:0;';
177
- let $tmpInner = document.createElement('div');
178
- $tmpInner.style.cssText = 'position:relative;';
179
- if (typeof hideNode === 'string') {
180
- $tmpInner.innerHTML = hideNode;
181
- }
182
- else {
183
- $tmpInner.appendChild(hideNode.cloneNode(true));
184
- }
185
- $tmp.appendChild($tmpInner);
186
- parent.appendChild($tmp);
187
- let rect = $tmpInner.children[0].getBoundingClientRect();
188
- parent.removeChild($tmp);
189
- return { width: rect.width, height: rect.height };
190
- }
1
+ /**
2
+ * web(浏览器端) DOM 文件操作
3
+ * 现今不推荐在使用这种方式,现在开发前端的时候,推荐使用一些成熟的框架例如:React、Preact、Vue、Angular、Svelte、Ember、Knockout等
4
+ * 在使用这些框架的时候额外的一些不可避免的 dom 操作时才使用这个工具;如果确实需要使用原生开发推荐使用 jquery 或者想要更精简的话可以使用 https://github.com/finom/bala 封装
5
+ */
6
+ const vendorPrefix = ['', '-webkit', '-moz-'];
7
+ /**
8
+ * 根据选择器获取节点
9
+ * @param {string} selector 选择器
10
+ */
11
+ export function elem(selector, dom) {
12
+ if (typeof selector === 'string') {
13
+ return (dom || document).querySelectorAll(selector);
14
+ }
15
+ else {
16
+ return [selector];
17
+ }
18
+ }
19
+ /**
20
+ * 为节点添加 class
21
+ * @param {HTMLElement} elem 待添加 class 的节点
22
+ * @param {string} clazz 需要添加的 class
23
+ */
24
+ export function addClass(elem, clazz) {
25
+ elem.classList.add(clazz);
26
+ }
27
+ /**
28
+ * 节点移除 class
29
+ * @param {HTMLElement} elem 待移除 class 的节点
30
+ * @param {string} clazz 需要移除的 class
31
+ */
32
+ export function removeClass(elem, clazz) {
33
+ elem.classList.remove(clazz);
34
+ }
35
+ /**
36
+ * 判断节点是否包含某个 class
37
+ * @param elem 待判断 class 的节点
38
+ * @param clazz 待判断的 class
39
+ * @returns
40
+ */
41
+ export function hasClass(elem, clazz) {
42
+ return elem.classList.contains(clazz);
43
+ }
44
+ /**
45
+ * 为节点添加 transition 属性,包括浏览器前缀
46
+ * @param {HTMLElement} element 需要添加 css Transition 属性的节点
47
+ * @param {string} value css transition 值
48
+ */
49
+ export function transition(element, value) {
50
+ vendorPrefix.forEach((prefix) => {
51
+ let t = prefix === '' ? 'transition' : prefix + 'Transition';
52
+ element.style[t] = value;
53
+ });
54
+ }
55
+ /**
56
+ * 为节点添加 transform 属性,包括浏览器前缀
57
+ * @param {HTMLElement} element 需要添加 css transform 属性的节点
58
+ * @param {string} value css transform 值
59
+ */
60
+ export function transform(element, value) {
61
+ vendorPrefix.forEach((prefix) => {
62
+ let t = prefix === '' ? 'transform' : prefix + 'Transform';
63
+ element.style[t] = value;
64
+ });
65
+ }
66
+ /**
67
+ * 为节点添加事件处理
68
+ * @param {HTMLElement} element 添加事件的节点
69
+ * @param {string} listener 事件名称
70
+ * @param {function} event 事件处理函数
71
+ * @param {boolean} onceOrConfig 是否是只运行一次的处理函数或者配置,其中 eventFlag 为 string,如果配置该项,则表明为委托事件
72
+ */
73
+ export function on(element, listener, fn, once = false) {
74
+ let eventExtra = { eventStop: false };
75
+ if (typeof once === 'boolean') {
76
+ eventExtra.once = once;
77
+ }
78
+ else {
79
+ eventExtra = once;
80
+ }
81
+ if (eventExtra.eventFlag != null) {
82
+ element.setAttribute(eventExtra.eventFlag, '__stop__');
83
+ element.addEventListener(listener, (e) => {
84
+ let target = e.target;
85
+ let flag = '';
86
+ do {
87
+ flag = target.getAttribute(eventExtra.eventFlag) || '';
88
+ if (flag === '') {
89
+ target = target.parentNode;
90
+ }
91
+ } while (flag === '');
92
+ if (flag !== '__stop__' || eventExtra.eventStop) {
93
+ fn(e, target, flag);
94
+ }
95
+ }, eventExtra);
96
+ }
97
+ else {
98
+ element.addEventListener(listener, fn, eventExtra);
99
+ }
100
+ }
101
+ /**
102
+ * 设置或获取节点的 innerHTML 属性
103
+ * @param element
104
+ * @param htmlstr 可选,如果传递该参数,则表示设置;否则表示获取
105
+ * @returns
106
+ */
107
+ export function html(element, htmlstr) {
108
+ if (htmlstr == null) {
109
+ return element.innerHTML;
110
+ }
111
+ else {
112
+ element.innerHTML = htmlstr;
113
+ return undefined;
114
+ }
115
+ }
116
+ /**
117
+ * 设置或获取节点的 textContent 属性
118
+ * @param element
119
+ * @param textstr 可选,如果传递该参数,则表示设置;否则表示获取
120
+ * @returns
121
+ */
122
+ export function text(element, textstr) {
123
+ if (textstr == null) {
124
+ return element.textContent;
125
+ }
126
+ else {
127
+ element.textContent = textstr;
128
+ return undefined;
129
+ }
130
+ }
131
+ /**
132
+ * 节点列表遍历
133
+ * @param elems
134
+ * @param fn 遍历到节点时的回调,回调第一个参数为遍历到的节点,第2个参数为 index;如果回调函数返回 true,则会终止遍历(break)
135
+ */
136
+ export function iterate(elems, fn) {
137
+ for (let i = 0, len = elems.length; i < len; i++) {
138
+ let r = fn(elems[i], i);
139
+ if (r === true) {
140
+ break;
141
+ }
142
+ }
143
+ }
144
+ /**
145
+ * 设置或获取节点 data-* 属性
146
+ * @param elem
147
+ * @param key data- 后面跟随的值
148
+ * @param value 如果传递该值表示获取;否则表示设置
149
+ * @returns
150
+ */
151
+ export function attr(elem, key, value) {
152
+ if (value != null) {
153
+ elem.setAttribute('data-' + key, value);
154
+ }
155
+ else {
156
+ return elem.getAttribute('data-' + key);
157
+ }
158
+ }
159
+ /**
160
+ * 获取指定节点的父节点
161
+ * @param el
162
+ * @returns
163
+ */
164
+ export function parent(el) {
165
+ return el.parentNode;
166
+ }
167
+ /**
168
+ * 获取隐藏节点的尺寸
169
+ * @param {string | HTMLElement} hideNode - The node to hide.
170
+ * @param parent - 添加临时节点的父节点,默认为: body.
171
+ * @returns The DOMRect of the element.
172
+ */
173
+ export function queryHideNodeSize(hideNode, parent = document.body) {
174
+ // 计算折叠菜单的高度
175
+ let $tmp = document.createElement('div');
176
+ $tmp.style.cssText = 'position:fixed;left:-1000px;top:-1000px;opacity:0;';
177
+ let $tmpInner = document.createElement('div');
178
+ $tmpInner.style.cssText = 'position:relative;';
179
+ if (typeof hideNode === 'string') {
180
+ $tmpInner.innerHTML = hideNode;
181
+ }
182
+ else {
183
+ $tmpInner.appendChild(hideNode.cloneNode(true));
184
+ }
185
+ $tmp.appendChild($tmpInner);
186
+ parent.appendChild($tmp);
187
+ let rect = $tmpInner.children[0].getBoundingClientRect();
188
+ parent.removeChild($tmp);
189
+ return { width: rect.width, height: rect.height };
190
+ }
package/lib/file.d.ts CHANGED
@@ -1,34 +1,31 @@
1
- declare const _default: {
2
- /**
3
- * 读取文件内容为JSON格式
4
- * @param filepath 读取的文件路径
5
- * @returns Promise<unknown>
6
- */
7
- readJSON<T>(filepath: string): Promise<T>;
8
- /**
9
- * 写入 JSON 格式的数据到文件
10
- * @param file 待写入的文件
11
- * @param data 待写入的数据
12
- * @param opts 写入配置
13
- * @property opts.json 是否写入 JSON 格式的数据,写入数据时对数据进行 JSON 格式化,默认为:true
14
- * @property opts.format 是否在写入 json 数据时,将 JSON 数据格式化2个空格写入, 默认为 true
15
- */
16
- write(file: string, data: any, opts?: {
17
- json: boolean;
18
- format: boolean;
19
- }): Promise<unknown>;
20
- /**
21
- * 遍历文件夹
22
- * @param dir 待遍历的目录
23
- * @param callback 遍历到文件后的回调
24
- * @param done 遍历完成后的回调
25
- */
26
- traverseDir(dir: string, callback?: (filename: string) => void, done?: () => void): void;
27
- /**
28
- * 根据文件的 stat 获取文件的 etag
29
- * @param filePath 文件地址
30
- * @returns file stat etag
31
- */
32
- statTag(filePath: string): Promise<string>;
33
- };
34
- export = _default;
1
+ /**
2
+ * 读取文件内容为JSON格式
3
+ * @param filepath 读取的文件路径
4
+ * @returns Promise<unknown>
5
+ */
6
+ export declare function readJSON<T>(filepath: string): Promise<T>;
7
+ /**
8
+ * 写入 JSON 格式的数据到文件
9
+ * @param file 待写入的文件
10
+ * @param data 待写入的数据
11
+ * @param opts 写入配置
12
+ * @property opts.json 是否写入 JSON 格式的数据,写入数据时对数据进行 JSON 格式化,默认为:true
13
+ * @property opts.format 是否在写入 json 数据时,将 JSON 数据格式化2个空格写入, 默认为 true
14
+ */
15
+ export declare function write(file: string, data: any, opts?: {
16
+ json: boolean;
17
+ format: boolean;
18
+ }): Promise<unknown>;
19
+ /**
20
+ * 遍历文件夹
21
+ * @param dir 待遍历的目录
22
+ * @param callback 遍历到文件后的回调
23
+ * @param done 遍历完成后的回调
24
+ */
25
+ export declare function traverseDir(dir: string, callback?: (filename: string) => void, done?: () => void): void;
26
+ /**
27
+ * 根据文件的 stat 获取文件的 etag
28
+ * @param filePath 文件地址
29
+ * @returns file stat etag
30
+ */
31
+ export declare function statTag(filePath: string): Promise<string>;
package/lib/file.js CHANGED
@@ -1,99 +1,96 @@
1
- "use strict";
2
- /** nodejs 文件操作工具类 */
3
- const path = require('path');
4
- const fs = require("fs");
5
- module.exports = {
6
- /**
7
- * 读取文件内容为JSON格式
8
- * @param filepath 读取的文件路径
9
- * @returns Promise<unknown>
10
- */
11
- readJSON(filepath) {
12
- return new Promise((resolve, reject) => {
13
- fs.readFile(path.resolve(filepath), 'utf-8', (err, data) => {
14
- if (err) {
15
- reject(err);
16
- }
17
- else {
18
- resolve(JSON.parse(data));
19
- }
20
- });
21
- });
22
- },
23
- /**
24
- * 写入 JSON 格式的数据到文件
25
- * @param file 待写入的文件
26
- * @param data 待写入的数据
27
- * @param opts 写入配置
28
- * @property opts.json 是否写入 JSON 格式的数据,写入数据时对数据进行 JSON 格式化,默认为:true
29
- * @property opts.format 是否在写入 json 数据时,将 JSON 数据格式化2个空格写入, 默认为 true
30
- */
31
- write(file, data, opts) {
32
- return new Promise((resolve, reject) => {
33
- let writeData = data.toString();
34
- opts = { json: true, format: true, ...(opts || {}) };
35
- if (opts.json === true && typeof data === 'object') {
36
- writeData = JSON.stringify(data, null, opts.format === true ? 2 : 0);
37
- }
38
- fs.writeFile(path.resolve(file), writeData, (err) => {
39
- if (err) {
40
- reject(err);
41
- }
42
- else {
43
- resolve(0);
44
- }
45
- });
46
- });
47
- },
48
- /**
49
- * 遍历文件夹
50
- * @param dir 待遍历的目录
51
- * @param callback 遍历到文件后的回调
52
- * @param done 遍历完成后的回调
53
- */
54
- traverseDir(dir, callback, done) {
55
- let t = -1; // 定时任务,简单延迟作为遍历完成计算
56
- function list(dr, cb, d) {
57
- fs.readdir(path.resolve(dr), { withFileTypes: true }, (err, files) => {
58
- if (err && err.errno === -4052) {
59
- // 本身就是文件
60
- if (typeof cb === 'function')
61
- cb(dr);
62
- if (typeof d === 'function')
63
- d(); // 遍历完成
64
- }
65
- else {
66
- for (let i = 0, len = files.length; i < len; i++) {
67
- const file = files[i];
68
- if (file.isFile()) {
69
- if (typeof cb === 'function')
70
- cb(path.join(dr, file.name));
71
- clearTimeout(t);
72
- t = setTimeout(() => {
73
- setImmediate(() => {
74
- if (typeof done === 'function') {
75
- done();
76
- }
77
- });
78
- }, 10);
79
- }
80
- else {
81
- // 文件夹
82
- list(path.join(dr, file.name), cb, d);
83
- }
84
- }
85
- }
86
- });
87
- }
88
- list(dir, callback, done);
89
- },
90
- /**
91
- * 根据文件的 stat 获取文件的 etag
92
- * @param filePath 文件地址
93
- * @returns file stat etag
94
- */
95
- async statTag(filePath) {
96
- let stat = await fs.promises.stat(filePath);
97
- return `${stat.size.toString(16)}-${stat.mtimeMs.toString(16)}`;
98
- },
99
- };
1
+ /** nodejs 文件操作工具类 */
2
+ import path from 'node:path';
3
+ import fs from 'node:fs';
4
+ /**
5
+ * 读取文件内容为JSON格式
6
+ * @param filepath 读取的文件路径
7
+ * @returns Promise<unknown>
8
+ */
9
+ export function readJSON(filepath) {
10
+ return new Promise((resolve, reject) => {
11
+ fs.readFile(path.resolve(filepath), 'utf-8', (err, data) => {
12
+ if (err) {
13
+ reject(err);
14
+ }
15
+ else {
16
+ resolve(JSON.parse(data));
17
+ }
18
+ });
19
+ });
20
+ }
21
+ /**
22
+ * 写入 JSON 格式的数据到文件
23
+ * @param file 待写入的文件
24
+ * @param data 待写入的数据
25
+ * @param opts 写入配置
26
+ * @property opts.json 是否写入 JSON 格式的数据,写入数据时对数据进行 JSON 格式化,默认为:true
27
+ * @property opts.format 是否在写入 json 数据时,将 JSON 数据格式化2个空格写入, 默认为 true
28
+ */
29
+ export function write(file, data, opts) {
30
+ return new Promise((resolve, reject) => {
31
+ let writeData = data.toString();
32
+ opts = { json: true, format: true, ...(opts || {}) };
33
+ if (opts.json === true && typeof data === 'object') {
34
+ writeData = JSON.stringify(data, null, opts.format === true ? 2 : 0);
35
+ }
36
+ fs.writeFile(path.resolve(file), writeData, (err) => {
37
+ if (err) {
38
+ reject(err);
39
+ }
40
+ else {
41
+ resolve(0);
42
+ }
43
+ });
44
+ });
45
+ }
46
+ /**
47
+ * 遍历文件夹
48
+ * @param dir 待遍历的目录
49
+ * @param callback 遍历到文件后的回调
50
+ * @param done 遍历完成后的回调
51
+ */
52
+ export function traverseDir(dir, callback, done) {
53
+ let t = -1; // 定时任务,简单延迟作为遍历完成计算
54
+ function list(dr, cb, d) {
55
+ fs.readdir(path.resolve(dr), { withFileTypes: true }, (err, files) => {
56
+ if (err && err.errno === -4052) {
57
+ // 本身就是文件
58
+ if (typeof cb === 'function')
59
+ cb(dr);
60
+ if (typeof d === 'function')
61
+ d(); // 遍历完成
62
+ }
63
+ else {
64
+ for (let i = 0, len = files.length; i < len; i++) {
65
+ const file = files[i];
66
+ if (file.isFile()) {
67
+ if (typeof cb === 'function')
68
+ cb(path.join(dr, file.name));
69
+ clearTimeout(t);
70
+ t = setTimeout(() => {
71
+ setImmediate(() => {
72
+ if (typeof done === 'function') {
73
+ done();
74
+ }
75
+ });
76
+ }, 10);
77
+ }
78
+ else {
79
+ // 文件夹
80
+ list(path.join(dr, file.name), cb, d);
81
+ }
82
+ }
83
+ }
84
+ });
85
+ }
86
+ list(dir, callback, done);
87
+ }
88
+ /**
89
+ * 根据文件的 stat 获取文件的 etag
90
+ * @param filePath 文件地址
91
+ * @returns file stat etag
92
+ */
93
+ export async function statTag(filePath) {
94
+ let stat = await fs.promises.stat(filePath);
95
+ return `${stat.size.toString(16)}-${stat.mtimeMs.toString(16)}`;
96
+ }