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

getElementsByTagNamegetを使用しているため、何をしているかに応じてdescendentsdescendentsライブ NodeListであるため、 Nodeを に追加すると長さが変化します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 に答える
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 に答える