ph-utils 0.2.22 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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
+ }