Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
airuikun opened this issue Apr 8, 2019 · 18 comments
Open

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

airuikun opened this issue Apr 8, 2019 · 18 comments

Comments

@airuikun
Copy link
Owner

airuikun commented Apr 8, 2019

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);
        }
    }
}
@songjunwei
Copy link

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

@waittu
Copy link

waittu commented Apr 9, 2019

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

外面空气好啊

@wuyuanaaa
Copy link

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

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

@Jewl
Copy link

Jewl commented Apr 22, 2019

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]);
            }
        }
    }
}

@magicyangmei
Copy link

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

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

@zhaojinxiong
Copy link

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

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

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

@fastCreator
Copy link

//尾递归
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)
}
}

@Seasonley
Copy link

Seasonley commented Jun 3, 2019

MDN - createTreeWalker

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

@GentleSen
Copy link

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

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

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

@GentleSen
Copy link

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]);
            }
        }
    }
}

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

@yoluxi
Copy link

yoluxi commented Jun 25, 2019

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

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

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

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

@Bjkb
Copy link

Bjkb commented Aug 7, 2019

// 借用一下前面的
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); // 直接进行解构操作
        }
    }
}

@gzwgq222
Copy link

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

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

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

@gzwgq222
Copy link

// 借用一下前面的
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]; 更喜欢这样,哈哈
非递归写法,很下饭啊

@francecil
Copy link

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 ?

@paddingme
Copy link

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);
        }
    }
}

@JiangWeixian
Copy link

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

为什么不使用这个

@ahalf-yuan
Copy link

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;
} 

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests