简体   繁体   中英

removing all text nodes from a particular div tag using javascript

i have some dynamically generated html from a php script. the php code looks like this

echo "<div id='categories'>\n";
foreach($category as $k => $v)
{
echo "<div class='category'>\n";
echo "<div id=\"$k\" class='cat_name'\n>$k</div>\n";
echo "<div id=\"$k".'_link"'." class='cat_link'>\n<a href=$v>Link</a>\n</div>\n";
echo "</div>\n";
}
echo "</div>\n";

i have a javascript file that tries to access the dom like this

var categories=document.getElementById('categories').childNodes;
for(i=0;i<categories.length;i++)
{
var link=categories[i].childNodes[1].childNodes[0].attributes['href'];
..
...
..

now this doesnt work as expected because there are text nodes in the html. when i used the firebug console to try this

document.getElementById('categories').childNodes[0].nodeType; // displays 3 

it displays 3 which means that the node is a text node . i tried adding document.normalize(); in window.onload like this

window.onload=function() {
document.normalize();
var categories=document.getElementById('categories').childNodes;
...
...

but the text nodes remain in the html. how can i remove all the text nodes. now i dont think there is any method like getElementByType() so how do i get all text nodes.

EE2015 syntax:

 var elm = document.querySelector('ul'); console.log(elm.outerHTML); // remove all text nodes [...this.elm.childNodes].forEach(elm => elm.nodeType != 1 && elm.parentNode.removeChild(elm)) console.log(elm.outerHTML);
 <ul> <li>1</li> a <li>2</li> b <li>3</li> </ul>

Breakdown:

  1. Get all children
  2. Convert the HTMLCollection to an Array
  3. Traversing the Array and checking each item if it's of type text node
  4. If so, remove the item from the DOM

This will only remove direct-child text nodes and nothing deeper in the tree.


with NodeIterator :

 var elm = document.querySelector('ul') // print HTML BEFORE removing text nodes console.log(elm.outerHTML) // remove all text nodes var iter = document.createNodeIterator(elm, NodeFilter.SHOW_TEXT) var node; while (node = iter.nextNode()) { node.parentNode.removeChild(node) } // print HTML AFTER removing text nodes console.log(elm.outerHTML)
 <ul> <li>1</li> <li>2</li> <li>3<span>4</span></li> </ul>

Use .children instead of .childNodes to target elements only (no text nodes):

   // --------------------------------------------------v
var categories=document.getElementById('categories').children;

FF3 doesn't support that property, so if you're supporting that browser, you'll need a method to replicate it.

function children( parent ) {
    var node = parent.firstChild;
    var result = [];
    if( node ) {
        do {
            if( node.nodeType === 1 ) {
                result.push( node );
            }
        } while( node = node.nextSibling )
    }
    return result;
}
var parent = document.getElementById('categories');
var categories= parent.children || children( parent );

Also note that IE will give you comment nodes as well, so it would be better if your markup didn't include comments.

Why don't you use getElementsByClassName MDC docs instead ?

var categories=document.getElementByClassName('category');

For browsers that do not natively support it look at these implementations : http://ejohn.org/blog/getelementsbyclassname-speed-comparison/

Check each node in your loop and if it's a text node, then either remove it as you said or do nothing. If it's not a text node, do what action you want to do to it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM