Skip to content

Commit a282ce0

Browse files
committed
fix: forEachDeep support traversal NodeList
1 parent e62ea8d commit a282ce0

File tree

5 files changed

+48
-13
lines changed

5 files changed

+48
-13
lines changed

rollup.config.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import json from '@rollup/plugin-json';
33
import typescript from '@rollup/plugin-typescript';
44
import resolve from '@rollup/plugin-node-resolve';
55
import subpathExternals from 'rollup-plugin-subpath-externals';
6-
import { dts } from 'rollup-plugin-dts';
6+
// import { dts } from 'rollup-plugin-dts';
77
import clear from 'rollup-plugin-clear';
88
import pkg from './package.json' assert { type: 'json' };
99
import terser from '@rollup/plugin-terser';
@@ -52,7 +52,7 @@ export default [
5252
tsconfig: 'tsconfig.json',
5353
include: ['src/**/*.ts'],
5454
// declaration: true,
55-
declarationMap: true,
55+
// declarationMap: true,
5656
outDir: 'dist/esm'
5757
}),
5858
json()
@@ -77,7 +77,7 @@ export default [
7777
tsconfig: 'tsconfig.json',
7878
include: ['src/**/*.ts'],
7979
// declaration: true,
80-
declarationMap: true,
80+
// declarationMap: true,
8181
outDir: 'dist/cjs'
8282
}),
8383
json()

src/tree.ts

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { objectOmit } from './object';
2-
import { AnyObject, isEmpty, isObject, objectHas } from './type';
2+
import { AnyObject, isEmpty, isNodeList, isObject, objectHas } from './type';
33

44
export interface IFieldOptions {
55
keyField: string;
@@ -26,7 +26,7 @@ export interface IFilterCondition<V> {
2626
}
2727

2828
/**
29-
* 树遍历函数(支持continue和break操作), 可用于insert tree item 和 remove tree item
29+
* 树遍历函数(支持continue和break操作), 可用于遍历Array和NodeList类型的数据
3030
* @param {ArrayLike<V>} tree 树形数据
3131
* @param {Function} iterator 迭代函数, 返回值为true时continue, 返回值为false时break
3232
* @param {options} options 支持定制子元素名称、反向遍历、广度优先遍历,默认{
@@ -46,13 +46,19 @@ export function forEachDeep<V>(
4646
parent: V | null,
4747
level: number
4848
) => boolean | void,
49-
options: { childField?: string; reverse?: boolean; breadthFirst?: boolean } = {
49+
options: { childField?: string; reverse?: boolean; breadthFirst?: boolean; isDomNode?: boolean } = {
5050
childField: 'children',
5151
reverse: false,
52-
breadthFirst: false
52+
breadthFirst: false,
53+
isDomNode: false
5354
}
5455
): void {
55-
const { childField = 'children', reverse = false, breadthFirst = false } = isObject(options) ? options : {};
56+
const {
57+
childField = 'children',
58+
reverse = false,
59+
breadthFirst = false,
60+
isDomNode = false
61+
} = isObject(options) ? options : {};
5662
let isBreak = false;
5763
const queue: {
5864
item: V;
@@ -80,7 +86,7 @@ export function forEachDeep<V>(
8086
} else if (re === true) {
8187
continue;
8288
}
83-
if (item && Array.isArray(item[childField])) {
89+
if (item && (isDomNode ? isNodeList(item[childField]) : Array.isArray(item[childField]))) {
8490
walk(item[childField], item, level + 1);
8591
}
8692
}
@@ -98,7 +104,7 @@ export function forEachDeep<V>(
98104
continue;
99105
}
100106

101-
if (item && Array.isArray(item[childField])) {
107+
if (item && (isDomNode ? isNodeList(item[childField]) : Array.isArray(item[childField]))) {
102108
walk(item[childField], item, level + 1);
103109
}
104110
}
@@ -122,7 +128,7 @@ export function forEachDeep<V>(
122128
continue;
123129
}
124130

125-
if (item && Array.isArray(item[childField])) {
131+
if (item && (isDomNode ? isNodeList(item[childField]) : Array.isArray(item[childField]))) {
126132
walk(item[childField], item, level + 1);
127133
}
128134
}
@@ -140,7 +146,7 @@ export function forEachDeep<V>(
140146
continue;
141147
}
142148

143-
if (item && Array.isArray(item[childField])) {
149+
if (item && (isDomNode ? isNodeList(item[childField]) : Array.isArray(item[childField]))) {
144150
walk(item[childField], item, level + 1);
145151
}
146152
}

src/type.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ export function isEmpty(value: any): boolean {
205205
* Checks if `value` is an NodeList object
206206
*/
207207
export function isNodeList(value: any) {
208-
return NodeList.prototype.isPrototypeOf(value);
208+
return isUndefined(NodeList) ? false : NodeList.prototype.isPrototypeOf(value);
209209
}
210210

211211
export default typeIs;

test/tree.test.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,26 @@ test('forEachDeep', () => {
234234
res4.push(name);
235235
});
236236
expect(res4).toEqual(['row1', 'row2']);
237+
238+
const divEl = document.createElement('div');
239+
divEl.textContent = 'div1';
240+
const divEl2 = document.createElement('div');
241+
divEl2.textContent = 'div2';
242+
const divEl3 = document.createElement('div');
243+
divEl3.textContent = 'div3';
244+
divEl2.appendChild(divEl3);
245+
const nodeContent: string[] = [];
246+
document.body.appendChild(divEl);
247+
document.body.appendChild(divEl2);
248+
249+
forEachDeep(
250+
document.body.children,
251+
val => {
252+
val.nodeType === Node.TEXT_NODE && nodeContent.push(val.nodeValue!);
253+
},
254+
{ isDomNode: true, childField: 'childNodes' }
255+
);
256+
expect(nodeContent).toEqual(['div1', 'div2', 'div3']);
237257
});
238258

239259
function generateTreeArray(length) {

test/type.test.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
isFunction,
99
isJsonString,
1010
isNaN,
11+
isNodeList,
1112
isNull,
1213
isNullish,
1314
isNumber,
@@ -149,3 +150,11 @@ test('isEmpty', () => {
149150
)
150151
).toBe(false);
151152
});
153+
154+
test('isNodeList', () => {
155+
const divEl = document.createElement('div');
156+
157+
document.body.appendChild(divEl);
158+
expect(isNodeList(document.body.childNodes)).toBe(true);
159+
expect(isNodeList([])).toBe(false);
160+
});

0 commit comments

Comments
 (0)