24

我一直在使用 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.each()相比,jQuery 的方法非常慢。我的问题是如何用纯 JS 来模仿这个?查找 a 中的所有元素,然后遍历节点。div

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

我已经尝试过其他事情,但这与我选择所有后代一样接近:

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

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

4 回答 4

40

你已经做对了

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用来 get descendentsdescendents是一个活动的 NodeList,所以它的长度会随着你添加更多的节点而改变ancestor。如果您需要避免这种情况,请在循环之前将其转换为数组

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

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

于 2013-07-23T21:58:53.863 回答
7

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

    // 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;
}
于 2013-07-23T22:01:15.440 回答
3

您可以使用 querySelectorAll 的 forEach 函数。

document.querySelectorAll('li').forEach(function(element) {
    console.log(element);
});
于 2017-11-06T19:08:19.683 回答
2

我在@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 进行实时修改,因为样式属性可能具有导致浏览器多次重绘的属性。

于 2013-07-24T11:56:37.217 回答