technology-blog icon indicating copy to clipboard operation
technology-blog copied to clipboard

第 4 题:如何遍历一个dom树

Open airuikun opened this issue 5 years ago • 18 comments

function traversal(node) {
    //对node的处理
    if (node && node.nodeType === 1) {
        console.log(node.tagName);
    }
    var i = 0,
        childNodes = node.childNodes,
        item;
    for (; i < childNodes.length; i++) {
        item = childNodes[i];
        if (item.nodeType === 1) {
            //递归先序遍历子节点
            traversal(item);
        }
    }
}

airuikun avatar Apr 08 '19 08:04 airuikun

hello,请问为什么要把i定义在外面?

songjunwei avatar Apr 08 '19 10:04 songjunwei

hello,请问为什么要把i定义在外面?

外面空气好啊

waittu avatar Apr 09 '19 01:04 waittu

if (item.nodeType === 1) { //递归先序遍历子节点 traversal(item); }

这里的判断可以省略吧,毕竟递归之后又会重新判断

wuyuanaaa avatar Apr 09 '19 02:04 wuyuanaaa

function traversal(node) {
    const stack = [];
    stack.push(node);
    while(stack.length > 0) {
        const elem = stack.pop();
        if (elem && elem.nodeType === 1) {
            console.log(elem.tagName);

            const children = elem.children;
            const len = children.length;
            for (let i = 0; i < len; i++) {
                stack.push(children[i]);
            }
        }
    }
}

Jewl avatar Apr 22 '19 06:04 Jewl

hello,请问为什么要把i定义在外面?

这样效率高,在那本书上看到过这种写法

magicyangmei avatar Apr 24 '19 03:04 magicyangmei

hello,请问为什么要把i定义在外面?

这样效率高,在那本书上看到过这种写法

var 的话这个写里面和写外面是一样的把 变量提升 js 没有块级作用域把

zhaojinxiong avatar Apr 25 '19 15:04 zhaojinxiong

//尾递归 function traversal(nodes,deal) { let arr = [] for(let i=0;i<nodes.length;i++){ deal(nodes[i]) if(nodes[i].childNodes){ arr = arr.concat(nodes[i].childNodes) } } if(arr.length){ return traversal(arr,deal) } }

fastCreator avatar Jun 03 '19 08:06 fastCreator

MDN - createTreeWalker

var node,treeWalker = document.createTreeWalker(document.body,NodeFilter.SHOW_ELEMENT)
while(node=treeWalker.nextNode())
    console.log(node)

Seasonley avatar Jun 03 '19 13:06 Seasonley

if (item.nodeType === 1) { //递归先序遍历子节点 traversal(item); } 这里的判断可以省略吧,毕竟递归之后又会重新判断

不是元素节点的话没必要往后走了,这个判断还是要的

那是不是应该加一个console.log输出, 是不是就跟上面的console.log输出重复了?

GentleSen avatar Jun 04 '19 10:06 GentleSen

function traversal(node) {
    const stack = [];
    stack.push(node);
    while(stack.length > 0) {
        const elem = stack.pop();
        if (elem && elem.nodeType === 1) {
            console.log(elem.tagName);

            const children = elem.children;
            const len = children.length;
            for (let i = 0; i < len; i++) {
                stack.push(children[i]);
            }
        }
    }
}

非递归写法,可以的,很强

GentleSen avatar Jun 04 '19 10:06 GentleSen

hello,请问为什么要把i定义在外面?

这样效率高,在那本书上看到过这种写法

var 的话这个写里面和写外面是一样的把 变量提升 js 没有块级作用域把

是的 所以写在外面只是一起定义了变量 更清楚当前作用域定义了哪些变量

yoluxi avatar Jun 25 '19 02:06 yoluxi

// 借用一下前面的
function traversal(node) {
    if(!node){
       console.log(node);
       return;
    }
    const stack = Array.from(node);  // 获取的是 HTMLNodes 类数组对象,转成数组
    while(stack.length > 0) {
        const elem = stack.pop();
        if (elem && elem.nodeType === 1) {
            console.log(elem.tagName);
            const children = elem.children || [];
            children.length>0 && stack.push(...children); // 直接进行解构操作
        }
    }
}

Bjkb avatar Aug 07 '19 07:08 Bjkb

if (item.nodeType === 1) { //递归先序遍历子节点 traversal(item); }

这里的判断可以省略吧,毕竟递归之后又会重新判断

不满足条件就直接不后续处理了呗,省略条件 traversal 又会执行一遍(根本没什么意义)

gzwgq222 avatar Aug 30 '19 06:08 gzwgq222

// 借用一下前面的
function traversal(node) {
    if(!node){
       console.log(node);
       return;
    }
    const stack = Array.from(node);  // 获取的是 HTMLNodes 类数组对象,转成数组
    while(stack.length > 0) {
        const elem = stack.pop();
        if (elem && elem.nodeType === 1) {
            console.log(elem.tagName);
            const children = elem.children || [];
            children.length>0 && stack.push(...children); // 直接进行解构操作
        }
    }
}

const stack =[...node]; 更喜欢这样,哈哈 非递归写法,很下饭啊

gzwgq222 avatar Aug 30 '19 07:08 gzwgq222

function traversal(node) {
    const stack = [];
    stack.push(node);
    while(stack.length > 0) {
        const elem = stack.pop();
        if (elem && elem.nodeType === 1) {
            console.log(elem.tagName);

            const children = elem.children;
            const len = children.length;
            for (let i = 0; i < len; i++) {
                stack.push(children[i]);
            }
        }
    }
}

不是 queue ?

francecil avatar Dec 17 '19 10:12 francecil

function traversal(node) {
    let stack = [node];
    while(stack.length > 0){
        const curNode = stack.pop();
        if (curNode) {
            if (curNode.nodeType === 1) {
                console.log(curNode.tagName);
            }
            const childNodes = [...curNode.childNodes];
            stack = stack.concat(childNodes);
        }
    }
}

paddingme avatar Jan 14 '20 09:01 paddingme

https://developer.mozilla.org/zh-CN/docs/Web/API/NodeIterator

为什么不使用这个

JiangWeixian avatar Jul 21 '20 15:07 JiangWeixian

function bfsDom(node) {
    if(!node) return;

    let queue = [];
    queue.push(node);

    let i = 0;
    while(i < queue.length) {
        queue = [...queue, ...queue[i].childNodes];
        i++;
    }
    return queue;
} 

ahalf-yuan avatar Aug 27 '20 06:08 ahalf-yuan