循环遍历div-JS的所有子代



我一直在使用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");
    };
});

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

我试着搜索这个,但我能找到的似乎都是jQuery的答案——到处都是。

我尝试过其他方法,但这几乎是我选择所有后代的方法:

var children = document.getElementById('id').getElementsByTagName('*');
for( var i = 0; i<children.lengtth; i++){
    children[i].removeAttribute("style");
    console.log(children[i]);
}

你已经做对了

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

现在你只需要在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);
    }
}

根据您正在做的操作,因为您使用getElementsByTagName来获得descendents,所以descendents是一个liveNodeList,所以它的长度会随着向ancestor添加更多节点而变化。如果需要避免这种情况,请在循环之前将其转换为阵列

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

请参阅此要点以获得可重复使用的函数。

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

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

您可以使用querySelectorAll的forEach函数。

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

我在@Paul S.的回答中评论道,您也可以克隆节点并使用文档片段来添加新的嵌入。这里有一个例子:

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:

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

你可以在这里看到演示。

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

最新更新