Search code examples
javascripttextnode

Filter by class names for changing text, using Javascript TreeWalker


Following that discussion, I'd like to understand how to use TreeWalker to change text on textNodes filtered by class names.

I'd like to replace all numbers with "x" on <p class="french"> only.

There's a piece of solution here, but the final jQuery is not practical for me. I'd like to understand why my following solution doesn't work.

myfilter = function(node){
  if (node.className=="french")
  return NodeFilter.FILTER_ACCEPT
  else
  return NodeFilter.FILTER_SKIP;
}

var walker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT, myfilter, false);

 while (walker.nextNode()) {
    walker.currentNode.nodeValue.replace(/(\d)/gu, 'x');   
 }
<body>
<p>890008900089000</p>
<p class="french">890008900089000</p>
</body>


Solution

  • Your code

    • walks over all text nodes (NodeFilter.SHOW_TEXT)
    • where className=="french" and
    • replaces each digit in their value with "x"

    There are several problems.

    1. Text nodes have no class. You have to test their parent nodes class.
    2. Strings are immutable and you don't use the result of the replacement.
    3. You actually want to replace all numbers with "x", not all digits. (?)

    So change node.className to node.parentNode.className, \d to \d+, and assign the result of String#replace back to walker.currentNode.nodeValue:

    myfilter = function(node){
      if (node.parentNode.className=="french")
      return NodeFilter.FILTER_ACCEPT
      else
      return NodeFilter.FILTER_SKIP;
    }
    
    var walker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT, myfilter, false);
    
     while (walker.nextNode()) {
        walker.currentNode.nodeValue = walker.currentNode.nodeValue.replace(/\d+/g, 'x');   
     }