Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to replace text in html document without affecting the markup?

How can I write a javascript/jquery function that replaces text in the html document without affecting the markup, only the text content?

For instance if I want to replace the word "style" with "no style" here:

<tr>
<td style="width:300px">This TD has style</td>
<td style="width:300px">This TD has <span class="style100">style</span> too</td>
</tr>

I don't want the replacement to affect the markup, just the text content that is visible to the user.

like image 567
Sylvain Avatar asked Dec 03 '22 14:12

Sylvain


2 Answers

You will have to look for the text nodes on your document, I use a recursive function like this:

function replaceText(oldText, newText, node){ 
  node = node || document.body; // base node 

  var childs = node.childNodes, i = 0;

  while(node = childs[i]){ 
    if (node.nodeType == 3){ // text node found, do the replacement
      if (node.textContent) {
        node.textContent = node.textContent.replace(oldText, newText);
      } else { // support to IE
        node.nodeValue = node.nodeValue.replace(oldText, newText);
      }
    } else { // not a text mode, look forward
      replaceText(oldText, newText, node); 
    } 
    i++; 
  } 
}

If you do it in that way, your markup and event handlers will remain intact.

Edit: Changed code to support IE, since the textnodes on IE don't have a textContent property, in IE you should use the nodeValue property and it also doesn't implements the Node interface.

Check an example here.

like image 73
Christian C. Salvadó Avatar answered Jan 05 '23 06:01

Christian C. Salvadó


Use the :contains selector to find elements with matching text and then replace their text.

$(":contains(style)").each(function() {
  for (node in this.childNodes) {
    if (node.nodeType == 3) { // text node
      node.textContent = node.textContent.replace("style", "no style");
    }
  }
});

Unfortunately you can't use text() for this as it strips out HTML from all descendant nodes, not just child nodes and the replacement won't work as expected.

like image 42
cletus Avatar answered Jan 05 '23 06:01

cletus