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...