How to remove text (without removing inner elements) from a parent element using jquery

Imagine that I have something like the following (modified from http://viralpatel.net/blogs/jquery-get-text-element-without-child-element/)

<div id="foo">
    first
    <div id="bar1">
        jumps over a lazy dog!
    </div>
    second
    <div id="bar2">
        another jumps over a lazy dog!
    </div>
    third
</div>

How can I remove just (only text) "first", "second" and "third" from DOM without affecting any of the child elements.


If you want to remove all child text nodes you can use .contents() and then .filter() to reduce the matched set to only text nodes:

$("#foo").contents().filter(function () {
     return this.nodeType === 3; 
}).remove();​​​​​​​

Here's a working example.

Note: This will preserve any existing event handlers on the child elements, which answers using .html() will not do (since the elements are removed from the DOM and added back in).

Note 2: Answers in some of the linked questions show similar code to that in my answer here, but they use the nodeType constants (e.g. return this.nodeType === Node.TEXT_NODE). This is bad practice since IE below version 9 does not implement the Node property. It's safer to use the integers (which can be found in the DOM level 2 spec).


Here's a non-jQuery version which works in all major browsers back to IE 5, just to demonstrate how unscary life without jQuery is.

Demo: http://jsfiddle.net/timdown/aHW9J/

Code:

var el = document.getElementById("foo"), child = el.firstChild, nextChild;

while (child) {
    nextChild = child.nextSibling;
    if (child.nodeType == 3) {
        el.removeChild(child);
    }
    child = nextChild;
}

try this :

$("#foo").html($("#foo").find("div"));​

demo : http://jsfiddle.net/PXxC4/