I want to replace a particular string in (the text of) all the descendant elements of a given element.
innerHTML
cannot be used as this sequence can appear in attributes. I have tried using XPath, but it seems the interface is essentially read-only. Because this is limited to one element, functions like document.getElementsByTagName
cannot be used either.
Could any suggest any way to do this? Any jQuery or pure DOM method is acceptable.
Edit:
Some of the answers are suggesting the problem I was trying to work around: modifying the text directly on an Element will cause all non-Text child nodes to be removed.
So the problem essentially comes down to how to efficiently select all the Text nodes in a tree. In XPath, you can easily do it as //text()
, but the current XPath interface does not allow you to change these Text nodes it seems.
One way to do this is by recursion as shown in the answer by Bergi. Another way is to use the find('*')
selector of jQuery, but this is a bit more expensive. Still waiting to see if there' are better solutions.
The replace() method replace() is a built-in method in Python that replaces all the occurrences of the old character with the new character.
The replaceAll() method will substitute all instances of the string or regular expression pattern you specify, whereas the replace() method will replace only the first occurrence.
To make the method replace() replace all occurrences of the pattern you have to enable the global flag on the regular expression: Append g after at the end of regular expression literal: /search/g. Or when using a regular expression constructor, add 'g' to the second argument: new RegExp('search', 'g')
You can replace all occurrence of a single character, or a substring of a given String in Java using the replaceAll() method of java. lang. String class. This method also allows you to specify the target substring using the regular expression, which means you can use this to remove all white space from String.
Just use a simple selfmade DOM-iterator, which walks recursively over all nodes:
(function iterate_node(node) {
if (node.nodeType === 3) { // Node.TEXT_NODE
var text = node.data.replace(/any regular expression/g, "any replacement");
if (text != node.data) // there's a Safari bug
node.data = text;
} else if (node.nodeType === 1) { // Node.ELEMENT_NODE
for (var i = 0; i < node.childNodes.length; i++) {
iterate_node(node.childNodes[i]); // run recursive on DOM
}
}
})(content); // any dom node
A solution might be to surf through all available nodes (TextNodes included) and apply a regexp pattern on the results. To grab TextNodes as well, you need to invoke jQuerys .contents()
. For instance:
var search = "foo",
replaceWith = 'bar',
pattern = new RegExp( search, 'g' );
function searchReplace( root ) {
$( root ).contents().each(function _repl( _, node ) {
if( node.nodeType === 3 )
node.nodeValue = node.nodeValue.replace( pattern, replaceWith );
else searchReplace( node );
});
}
$('#apply').on('click', function() {
searchReplace( document.getElementById('rootNode') );
});
Example: http://jsfiddle.net/h8Rxu/3/
Reference: .contents()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With