简体   繁体   中英

Replace text at top-level of node without breaking formatting of children

If I have the following html code:

<div id="element">
Qwerty Foo Bar 
<span style="color: red;">This text should/will never be changed by the script.</span>
</div>

And I want to change "Foo" to "baz", I can do the following:

var element = document.getElementById('element');
element.innerText = element.innerText.replace('Foo', 'baz');

However this will destroy the formatting of the red text.

How can you do this?

I don't need cross-browser support, only support for chrome and I don't want to use a js framework. jsFiddle: http://jsfiddle.net/cLzJD/3/

You can iterate over the children and only modify text nodes:

var children = element.childNodes,
    child;

for(var i = children.length; i--; ) {
    child = children[i];
    if(child.nodeType === 3) {
        child.nodeValue = child.nodeValue.replace('Foo', 'baz');
    }
}

DEMO

Notes:

  • If you want to replace all occurrences of Foo , you have to use a regular expression: replace(/Foo/g, 'baz') .

  • The advantage of this approach is that event handlers bound through JavaScript will stay intact. If you don't need this, innerHTML will work as well.

Although @Felix Kling's solution is the best approach, in your special case you could use .innerHTML instead of .innerText .

element.innerHtml = element.innerHtml.replace('Foo', 'baz');

.replace() will only replace the first occurrence, so if you're sure there is no HTML content before your text, you can use it. Otherwise it could break your HTML.

You are losing the formatting because you're using innerText (which will return the contents with all the HTML stripped out). Just use innerHTML instead: http://jsfiddle.net/cLzJD/4/ (I've also changed the ids to be unique).

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