SO-64891962

by David Thomas

HTML

<h3 id="plop">I want to change this text <span id="trololo">bla bla bla</span> </h3>

<ul>
  <li>This text <em>should be</em> removed</li>
  <li>This <em>element</em> has <em>multiple</em> <q>HTML child-nodes</q> which should <em>not</em> be changed<strong>.</strong></li>
</ul>

CSS

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

q::before,
q::after {
  content: '"';
  color: #777;
}

ul li {
  margin: 0.2em 0 0 1.5em;
}
ul li::marker {
  content: "\00BB";
  color: #f90;
}

JavaScript

// declaring the function changeText() as a constant, using
// Arrow function syntax (since we don't use 'this' within
// the function); this takes two arguments:
// elem: a reference to the node whose text we're changing, and
// ...text: which combines all supplied Strings into an Array,
// using the rest operator:
const changeText = (elem, ...text) => {

  // initialises a counter:
  let counter = 0,
  
    // in the event that only one String is provided we make the
    // assumption that the supplied String should replace all
    // text-nodes:
    repeat = text.length === 1,
    // declared, but uninitialised, variables for later use:
    cache,
    _temp,
    beginsWithSpace,
    endsWithSpace;

  // retrieves the child-nodes of the given element-node, and we then
  // use NodeList.prototype.forEach() to iterate over those nodes:
  elem.childNodes.forEach(
    // n is a reference to the current Node of the NodeList:
    (n) => {
      // if the Node has a nodeType, and that nodeType is 3 it is
      // a textNode:
      if (n.nodeType && n.nodeType === 3) {
        // we cache the current nodeValue in the 'cache' variable:
        cache = n.nodeValue;
        // we use RegExp.prototype.test() which returns a Boolean
        // to see if the current nodeValue starts with a space:
        beginsWithSpace = (/^\s+/).test(cache);
        // ...or ends with a whitespace:
        endsWithSpace = (/\s+$/).test(cache);
        
        // here we assign the text - from the supplied argument -
        // to the _temp variable; if only one argument exists
        // (hence repeat is true) we use the first element of the
        // Array, otherwise - if repeat is false - we use the
        // String from the text Array at the index of counter, and
        // then increment the counter variable:
        _temp = repeat ? text[0] : [text[counter++]];
        
        // here we assign a new value to the current Node, using
        // a template-literal; if...