Iryn
Iryn

Reputation: 255

jquery: Making the replacement only on text nodes

I'm trying to parse a text as html, making some changes, and then again turning in back to plain text.

The changes that I'm going to make is bassically replacing some term with another (e.g. 'old' with 'new').

I only want to change the text types, not the attributes and properties of html elements (e.g. the href values should not be changed.).

Please see the code:

h= '<span myAtrib="something"><a href="old(this SHOULD NOT be changed)">old(this SHOULD be changed)</a></span>';

h=$("<div>"+ h +"</div>").find('span[myAtrib="something"]').html(function (i, oldHtml) {
    oldHtml = oldHtml.replace(/old/g, 'new');
return oldHtml;
}).end().html();

How should I make the replacement happen only on text nodes, or at least, how should I filter-out the anchor elements?

Upvotes: 0

Views: 61

Answers (2)

Arun P Johny
Arun P Johny

Reputation: 388316

Another approach to do the same is

h = $("<div id='root'>" + h + "</div>").find('span[myAtrib="something"]').find('*').addBack().contents().each(function () {
    if (this.nodeType == 3 && $.trim(this.nodeValue) != '') {
        this.nodeValue = this.nodeValue.replace(/old/g, 'new')
    }
}).end().end().end().end().html();

Demo: Fiddle

Upvotes: 1

Felix Kling
Felix Kling

Reputation: 816334

How should I make the replacement happen only on text nodes

By recursively iterating over all child nodes/descendants and testing whether the node is a text node or not:

function replace($element, from, to) {
    $element.contents().each(function() {
        if (this.nodeType === 3) { // text node
            this.nodeValue = this.nodeValue.replace(from, to);
        }
        else if (this.nodeType === 1) { // element node
            replace($(this), from, to);
        }
    });
}
var $ele = $("<div>"+ h +"</div>").find('span[myAtrib="something"]')
replace($ele, /old/g, "new");
var html = $ele.end().html();

DEMO

You can easily do this without jQuery as well.

Upvotes: 2

Related Questions