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