Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Remove or empty content of elements

Tags:

jquery

I have some HTML like this:

<div>TEXT
    <span>SPAN</span>
        <a href="">LINK</a>
</div>

I would like to remove the contents of the elements, usually I would do something like this:

$('*').empty(); 

or

$('*').contents().empty();

This however will remove/empty the first span and its content which is the div and link. What can I do to preserve the elements while emptying them? So the end result would be:

<span>
    <div></div>
    <a href=""></a>
</span>

Please note I'm looking for something 'universal' that can be applied to any HTML. The above is just an example, in reality the HTML structure would contain more data.

Example at JsFiddle

like image 943
Youss Avatar asked Mar 19 '13 21:03

Youss


3 Answers

Recursively loop through all nodes, and remove all children whose nodeType property equals 3 (Node.TEXT_NODE). jQuery cannot select just text nodes, so this can be done using vanilla JavaScript.

Example:

function removeText(node) {
    if (!node || !node.childNodes || !node.childNodes.length) return;
    for (var i=node.childNodes.length-1; i>=0; --i) {
        var childNode = node.childNodes[i];
        if (childNode.nodeType === 3) node.removeChild(childNode);
        else if (childNode.nodeType === 1) removeText(childNode);
    }   
}

Or, packed in a jQuery plugin:

$.fn.removeText = function() {
    for (var i=this.length-1; i>=0; --i) removeText(this[i]);
    return this;
};

http://jsfiddle.net/hcKsX/

like image 108
Rob W Avatar answered Oct 21 '22 07:10

Rob W


Get the children of the parent item and set their html like thus:

$('#myspan').children().html('');

jsFiddle

like image 29
Marcus Avatar answered Oct 21 '22 07:10

Marcus


These solutions are all ok, but none of them satisfy your condition.

Example #1: remove all text inside leaf nodes

$('body *:not(:has(*))').empty()

result:

<span>SPAN
    <div></div>
    <a href=""></a>
</span>

Example #2: remove all text inside children of just one node

$('body span').children().html('')

result:

<span>SPAN
    <div></div>
    <a href=""></a>
</span>

(same as above). However, this solution would not work if there were more than 2 levels of nesting.

Other solutions have similar downfalls.

The real problem here is there's no good way to clear text out of a node that is both a parent node AND a text node. You should either hack something together or re-render your view each time.

like image 1
Connor McArthur Avatar answered Oct 21 '22 06:10

Connor McArthur