我一直在使用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]);
}
答案 0 :(得分:27)
你已经做得对了
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
是直播 NodeList ,因此当您向ancestor
添加更多节点时,它的长度会发生变化。如果您需要避免这种情况,请在循环
decendents = Array.prototype.slice.call(decendents);
有关可重复使用的功能,请参阅this gist。
答案 1 :(得分:3)
// 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;
}
答案 2 :(得分: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);
}
您可以看到演示here.
克隆节点会阻止DOM的实时修改,因为style属性可能具有导致浏览器多次重绘的属性。
答案 3 :(得分:2)
您可以将querySelectorAll用于每个函数。
document.querySelectorAll('li').forEach(function(element) {
console.log(element);
});