javascript - 指定body节点下的任意元素节点,如何快速算出它是body的第几代,第几个子孙元素?
天蓬老师
天蓬老师 2017-04-11 11:38:07
[JavaScript讨论组]

我们开发时有一个需求,让我几乎崩溃。
需求总结后就是:
指定body节点下的任意元素节点,算出它是body节点的第几个儿子的,第几个孙子。这个关系可以很长。比如某些很深的元素节点,可能结论是:某元素节点是body节点的第2个儿子的第3个儿子的第1个儿子的第9个儿子。

(PS:textNode要跳过,只计算elementNode)

我实在搞不定了,搜资料也没找到对口的,求大神帮忙,分享一些资料也好啊。

天蓬老师
天蓬老师

欢迎选择我的课程,让我们一起见证您的进步~~

全部回复(3)
高洛峰
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>

<body>
    <p></p>
    <p>
        <p>
            <span>
      你是一个
      <a href="http://www.baidu.com">链接</a>
      吧
    </span>
            <span>
      另一个 <a href="http://mail.163.com">链接</a>
    </span>
        </p>
    </p>
    <ul></ul>
    <ul>
        <li>没事</li>
        <li>
            <ol>
                <li>第0</li>
                <li>第1</li>
                <li>第3是个 <a href="#" id='lastA'>链接</a></li>
            </ol>
        </li>
    </ul>
</body>
<script>
function Path(el) {
    if (!el) return;
    const res = [{
        el: el,
        index: findIndex(el),
        type: el.nodeName
    }];
    while (el.parentNode && el.parentNode !== document.documentElement) {
        res.push({
            el: el.parentNode,
            index: findIndex(el.parentNode),
            type: el.parentNode.nodeName
        });
        el = el.parentNode
    };
    return res.reverse().reduce(function(prev, item) {
        prev += '第' + item.index + '个' + item.type + '下'
        return prev
    }, '').replace(/下$/, '')
}

function findIndex(el) {
    let index = 1;
    while (el.previousSibling) {
        if (el.previousSibling.nodeType === 1 && el.parentNode !== document.documentElement)
            index++;

        el = el.previousSibling
    }
    return index
}
console.log(Path(document.getElementById('lastA')))
</script>

</html>
怪我咯

如果用 jQuery 还是比较好处理的(不过这种处理性能肯定不会好)

function findIndexes(jo) {
    var parents = jo.parentsUntil("body");
    return parents.map(function() {
        return $(this).index();
    }).toArray().reverse();
}

https://jsfiddle.net/7sak70gu/

怪我咯
  1. 这个需求我觉得从安置dom节点的时候就应该考虑到,比如说dom节点与一个数据结构相对应,或者对dom节点做hash(没错就是Vitrual DOM的思路)

  2. 不然最优的方案只能是逆向宽搜(通过父节点遍历到目前是第几个,如果父节点不是body就继续这步骤),不过,读取DOM节点的代价也是高昂的不亚于操作DOM节点,适用于DOM数量级较小的页面

  3. 如果上了React等,那可以简化一点,其实和第一个数据相同

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号