Alex Rivera | Logout

Loop through all descendants of a div - JS only

Asked 2013-07-23T21:41:15.190
28

I've been using jQuery to do this:

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

But I've been reading that jQuery's .each() method is quite slow when compared to a simple for loop (jsPerf). My question is how can I mimic this with pure JS? Find all elements within a div, then loop through the nodes.

I've tried to search for this but all I can seem to find are jQuery answers - everywhere.

I've tried other things but this was as close as I got to selecting all descendants:

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

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

1 Answer

2

I commented in @Paul S.'s answer that you could can also clone the node and use a document fragment to add new embeds. Here is an example:

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

You can see the demo here.

Cloning the node prevents the live modification of the DOM since the style attribute can have properties that cause the browser to repaint numerous times.

answered 2013-07-24T11:56:37.217

Your Answer