从JS遍历DOM树学算法

栏目: JavaScript · 发布时间: 6年前

内容简介:从简单的需求/面试题谈起自定义一个方法去检查DOM中某个ID的元素。类似getElementById.先推荐阅读下:

从简单的需求/面试题谈起

自定义一个方法去检查DOM中某个ID的元素。类似getElementById.

先推荐阅读下:

广度优先 .

深度优先搜索

// HTML结构如下

<div class="wrapper">
    <section class="header">
        <div class="logo"></div>
    </section>
    <section class="main">
        <div class="sidebar">
            <ul class="menu">
                <li class='li'>
                    <a href="" id='demo'>li1-a</a>
                </li>
                <li class='li'>
                    <a href="">li2</a>
                </li>
            </ul>
        </div>
    </section>
    <section class="footer">
        <div class="copyright"></div>
    </section>
</div>
复制代码

简单画了下DOM节点(只考虑元素节点)图:

从JS遍历DOM树学算法

代码实现

  • 深度优先, 递归实现
const cusGetElementByIdByDFS = function (parentNode, id) {
    // 深度优先, 递归实现
    if (parentNode) {
        let target = null;
        const children = Array.from(parentNode.children);
        if (parentNode.id === id) {
            return parentNode;
        }
        for (let i = 0; i < children.length; i++) {
            target = cusGetElementByIdByDFS(children[i], id);
            if (target) {
                return target;
            }
        }
    }
    return null;
}

复制代码
// 测试代码
console.log(cusGetElementByIdByDFS(document.querySelector('.wrapper') , 'demo'))
复制代码
  • 深度优先, 非递归实现, 使用栈
const cusGetElementByIdByDFS2 = function (parentNode, id) {
    if (!parentNode) {
        return null;
    }
    // 深度优先, 非递归实现, 使用栈
    let stack = [];
    if (parentNode.id === id) {
        return parentNode;
    }
    for (let i = parentNode.children.length; i > 0; i--) {
        stack.push(parentNode.children[i - 1]);
    }
    while (stack.length) {
        let node = stack.pop();
        if (node.id === id) {
            return node;
        } else {
            if (node.children.length > 0) {
                stack = Array.from(node.children).concat(stack);
            }
        }
    }
}
复制代码
// 测试代码
console.log(cusGetElementByIdByDFS2(document.querySelector('.wrapper') , 'demo'))
复制代码
  • 广度优先 非递归实现
const cusGetElementByIdByBFS = function (parentNode, id) {
    // 广度优先 非递归实现
    // 队列的思想: 采用出队的方式遍历节点,如果遍历到的节点有子节点,则将子节点入队
    const layer = []; // 按照顺序存放每个层级的每个节点
    if (parentNode) {
        // 初始化layer
        // 节点深度从父节点开始算起
        layer.push({
            node: parentNode,
            depth: 1
        });
        while (layer.length > 0) {
            const root = layer.shift(); // 出队
            if (root.node.id === id) {
                return root; // 包括对应节点和节点深度
            } else {
                if (root.node.children.length > 0) {
                    Array.from(root.node.children).forEach(node => {
                        layer.push({
                            node,
                            depth: root.depth + 1
                        })
                    })
                }
            }
        }
    }
    return null;
}
复制代码
// 测试代码
console.log(cusGetElementByIdByBFS(document.querySelector('.wrapper') , 'demo'))
复制代码
从JS遍历DOM树学算法

后续看细下算法书再做补充, 初次学习有勘误请指出。


以上所述就是小编给大家介绍的《从JS遍历DOM树学算法》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

程序员的数学思维修炼(趣味解读)

程序员的数学思维修炼(趣味解读)

周颖 / 清华大学出版社 / 2014-4-1 / 45.00元

本书是一本专门为程序员而写的数学书,介绍了程序设计中常用的数学知识。本书门槛不高,不需要读者精通很多高深的数学知识,只需要读者具备基本的四则运算、乘方等数学基础知识和日常生活中的基本逻辑判断能力即可。本书拒绝枯燥乏味的讲解,而是代之以轻松活泼的风格。书中列举了大量读者都很熟悉,而且非常有趣的数学实例,并结合程序设计的思维和算法加以剖析,可以训练读者的数学思维能力和程序设计能力,进而拓宽读者的视野,......一起来看看 《程序员的数学思维修炼(趣味解读)》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具