美文网首页
原生JS模拟出jquery的find()方法(简单递归)

原生JS模拟出jquery的find()方法(简单递归)

作者: DHFE | 来源:发表于2018-07-19 23:46 被阅读1184次

jQuery中的find()函数可以在给定的父元素中,获得当前父元素下指定的子元素集合。
关于find()的具体使用就不细说了,重点是如何使用原生JS来实现一样的功能。

当时想的方法是用递归来完成DOM树的遍历。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <div class="carousel" id="id_carousel">
        <ul class="img-ct">
            <li id="0">
                <a href="#">
                    <p>p0</p>
                </a>
            </li>
            <li id="1">
                <a href="#">
                    <p>p1</p>
                </a>
            </li>
        </ul>
    </div>
    <script>
        function findRecursion(parent, label) {
            for (var i = 0; i < parent.children.length; i++) {
                console.log(parent.children[i]);
                findRecursion(parent.children[i], label);
            }
        }
        /*
        ul.img-ct {compact: false, type: "", title: "", lang: "", translate: true, …}
        li#0 {value: 0, type: "", title: "", lang: "", translate: true, …}
        a {target: "", download: "", ping: "", rel: "", relList: DOMTokenList(0), …}
        p {align: "", title: "", lang: "", translate: true, dir: "", …}
        li#1 {value: 0, type: "", title: "", lang: "", translate: true, …}
        a {target: "", download: "", ping: "", rel: "", relList: DOMTokenList(0), …}
        p {align: "", title: "", lang: "", translate: true, dir: "", …}
        */
    </script>
</body>
</html>

其实自己对递归不是很熟练(科班出身学过算法的优势马上体现出来了有没有!),了解也不是很深刻,以至于当时写出来甚至都不知道如何运行的,后面一步一步打断点运行后才了解,也知道了为什么jQuery中find()的源码没有使用这种方法来遍历DOM。

调试界面
可以看到在调用堆栈中,有5个findRecursion()函数在堆栈内执行,此时遍历DOM深度是遍历到第一个li元素内的p元素上。由于p本身没有后代元素(children.length=0),不会再继续调用函数递归下去,执行栈弹出函数,i自增......直到碰到下一个children.length>1的元素,继续遍历下去。

实际上,节点中每存在一个后代节点,就会执行一次函数,如果元素节点很多很深,很容易造成栈溢出。

        <ul class="img-ct">
            <li id="0">
                <a href="#">
                    <p>p0</p>
                </a>
            </li>
            <li id="1">
                <a href="#">
                    <p>p1</p>
                </a>
            </li>
        </ul>

这是优化了一下函数,简单模拟了find()的功能。加入class、id、tagName参数用于对比,数组用于保存符合功能的元素。

var result = [];
function findRecursion(parent,label) {
    for (var i = 0; i < parent.children.length; i++) {

        if (([].indexOf.call(parent.children[i].classList,label) !== -1) || parent.children[i].id === label || parent.children[i].tagName === label) {
            result.push(parent.children[i]);
        }

        findRecursion(parent.children[i], label);
    }
}

findRecursion(document.querySelectorAll(".carousel")[0],"P");   // Array(4) [p, p, p, p.p3]
console.log(result);
result = [];

findRecursion(document.querySelectorAll(".carousel")[0],"3");   // Array(1) [li#3]
console.log(result);
result = [];

findRecursion(document.querySelectorAll(".carousel")[0],"img-ct");   // Array(1) [ul.img-ct]
console.log(result);
result = [];

测试HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <div class="carousel" id="id_carousel">
        <ul class="img-ct">
            <li id="0">
                <a href="#"><p>p0</p></a>
            </li>
            <li id="1">
                <a href="#"><p>p1</p></a>
            </li>
            <li id="2">
                <a href="#"><p>p2</p></a>
            </li>
            <li id="3">
                <a href="#"><p class="p3">p3</p></a>
            </li>
        </ul>
    </div>
</body>
</html>

当然问题也有很多,如没有使用this,参数类型不严谨,每执行一次result数组要归0等等。

关于尾递归


待更

相关文章

  • 原生JS模拟出jquery的find()方法(简单递归)

    jQuery中的find()函数可以在给定的父元素中,获得当前父元素下指定的子元素集合。关于find()的具体使用...

  • jQuery

    jQuery简介 jQuery其实就是原生JS封装之后的一种方法。比起原生JS的操作要方便许多,原生JS的DOM操...

  • jQuery简介

    什么是jQuery? jQuery其实就是原生JS封装之后的一种方法。比起原生JS的操作要方便许多,原生JS的DO...

  • 20、jQuery 事件机制

    20、jQuery 事件机制 原生js事件与jQuery事件: (1)用原生的js给div注册事件 原生js注册相...

  • 00-jQuery初识

    什么是jQuery jQuery是一个JavaScript库 jQuery可以简化原生JS的操作 对比原生JS,写...

  • 使用原生js实现复制对象及扩展

    使用原生js实现复制对象,扩展对象,类似JQuery中的extend()方法

  • AJAX实现

    原生js jquery

  • jQuery排序和动画

    jQuery排序 eq()方法 jQuery中获得的对象,内部包含选择的一组原生JS对象,在jQuery对象中会进...

  • 点击回到顶部的js方法和jq方法

    js方法: 再来看看jquery方法,简单了许多

  • js给元素添加类的方法

    原生js中添加类的方法 .jquery中添加类的方法 检查是否含有某个类的方法 例子:html部分 css部分 js部分

网友评论

      本文标题:原生JS模拟出jquery的find()方法(简单递归)

      本文链接:https://www.haomeiwen.com/subject/xfogpftx.html