javascript 循环遍历 div 的所有后代 - 仅限 JS

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17821560/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 09:45:34  来源:igfitidea点击:

Loop through all descendants of a div - JS only

javascriptoptimization

提问by Jonny Sooter

I've been using jQuery to do this:

我一直在使用 jQuery 来做到这一点:

$element.find("*").each(function() {
    var $this = $(this);

    $this.removeAttr("style width align");

    if ($this.is("embed")) {
        $element.append("<div class='video'></div>");
        $this.attr("width", 640).attr("height", 360).parent().appendTo("#" + element + " .video");
    };
});

But I've been reading that jQuery's .each()method is quite slow when compared to a simple for loop (jsPerf). My question is how can I mimic this with pure JS? Find all elements within a div, then loop through the nodes.

但是我一直在读到,.each()与简单的 for 循环 ( jsPerf)相比,jQuery 的方法非常慢。我的问题是如何用纯 JS 模仿这个?查找 a 中的所有元素div,然后遍历节点。

I've tried to search for this but all I can seem to find are jQuery answers - everywhere.

我试图搜索这个,但我似乎只能找到 jQuery 答案 - 无处不在。

I've tried other things but this was as close as I got to selecting all descendants:

我已经尝试了其他的东西,但这与我选择所有后代一样接近:

var children = document.getElementById('id').getElementsByTagName('*');

for( var i = 0; i<children.lengtth; i++){
    children[i].removeAttribute("style");
    console.log(children[i]);
}

回答by Paul S.

You're already doing it right

你已经做对了

var ancestor = document.getElementById('id'),
    descendents = ancestor.getElementsByTagName('*');
    // gets all descendent of ancestor

Now you just need to loop over children

现在你只需要循环 children

var i, e, d;
for (i = 0; i < descendents.length; ++i) {
    e = descendents[i];
    e.removeAttribute('style');
    e.removeAttribute('width');
    e.removeAttribute('align');
    if (e.tagName === 'EMBED') {
        d = document.createElement('div');
        d.setAttribute('class', 'video');
        ancestor.appendChild(d);
    }
}

Depending on what you're doing, because you're using getElementsByTagNameto get descendents, descendentsis a liveNodeList, so it's length will change as you add more Nodesto ancestor. If you need to avoid this, convert it to an Arraybefore the loop

根据你在做什么,因为你用getElementsByTagName得到descendentsdescendents是一个活的节点列表,从而为你增加更多的它的长度会改变的节点ancestor。如果您需要避免这种情况,请在循环之前将其转换为数组

decendents = Array.prototype.slice.call(decendents);

See this gistfor a reusable function.

有关可重用功能,请参阅此要点

回答by nicksweet

could you just use something as simple as this?

你能用这么简单的东西吗?

    // get a handle to the div you want.
var div = document.getElementById('someID'),
    // get an array of child nodes
    divChildren = div.childNodes;

for (var i=0; i<divChildren.length; i++) {
    divChildren[i].style.width = null;
    divChildren[i].style.textAlign = null;
}

回答by Daniel Eduardo Delgado Diaz

You can use querySelectorAll's forEach function.

您可以使用 querySelectorAll 的 forEach 函数。

document.querySelectorAll('li').forEach(function(element) {
    console.log(element);
});

回答by stavarotti

I commented in @Paul S.'s answer that you could can also clone the node and use a document fragment to add new embeds. Here is an example:

我在@Paul S. 的回答中评论说,您还可以克隆节点并使用文档片段添加新的嵌入。下面是一个例子:

HTML:

HTML:

<div>
    <div id="container">
        <div align="right">child</div>
        <div align="center">child</div>
        <embed src="" width="0" height="0" />
        <div align="center">child</div>
        <div style="width: 40px">child</div>
        <div style="font-size: 100px">child</div>
        <div width="60%">child</div>
        <embed src="" width="0" height="0"/>
        <div width="60%">child</div>
    </div>
</div>

JS:

JS:

var elm,
    clone,
    doc,
    next,
    fragment,
    live = document.getElementById("container");

if (live !== null) {
    fragment = document.createDocumentFragment();
    clone = live.cloneNode(true);
    next = clone.firstChild;
    while(next !== null) {
        if (next.nodeName !== "#text") {
            next.removeAttribute('style');
            next.removeAttribute('width');
            next.removeAttribute('align');

            if (next.tagName === 'EMBED') {
                doc = document.createElement('div');
                doc.setAttribute('class', 'video');
                doc.innerHTML = "EMBED detected, adding div...";
                fragment.appendChild(doc);
            }
        }
        next = next.nextSibling;
    }
    clone.appendChild(fragment);
    live.parentNode.replaceChild(clone, live);
}

You can see the demo here.

您可以在此处查看演示

Cloning the node prevents the live modification of the DOM since the style attribute can have properties that cause the browser to repaint numerous times.

克隆节点可以防止对 DOM 进行实时修改,因为样式属性可能具有导致浏览器多次重绘的属性。