Jerry
Jerry

Reputation: 1583

JS/Jquery Replace inner text without destroy event

This is the html:

<div id="div001">
  This is ${Row.1}.
  <p>${Row.2} explain something else.</p>
  <p>${Row.3} welcome you. <span>${Hello.World}, this is a new world.</span></p>
</div>

What I want to do is replace the ${Row.1} to the text Row 1 without replacing entire div001 DIV. Because this will destroyed the event on the <p> & <span>.

I currently able to achieve loop through all element and find the child node(without html tag in there), in this case is the first <p> & <span>, and replace the word with JQUERY $(ele).text().

But i still can't find a way replace the ${Row.1} & ${Row.3}.

Please advise me, thank you.

Upvotes: 1

Views: 332

Answers (2)

Obsidian Age
Obsidian Age

Reputation: 42384

The easiest way that I can think of would be to wrap it in a <span>. Then you could target it with $('#div001 > span'):

$('#div001 > span').text('Replaced');
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div id="div001">
  <span>This is ${Row.1}.</span>
  <p>${Row.2} explain something else.</p>
  <p>${Row.3} welcome you. <span>${Hello.World}, this is a new world.</span></p>
</div>

If you explicitly want to replace the ${Row.x} components, you can wrap those parts in <span> tags with an associated ID / class, and use that to target them:

$('#one, #three').text('Replaced');
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div id="div001">
  This is <span id="one">${Row.1}</span>.
  <p><span id="two">${Row.2}</span> explain something else.</p>
  <p><span id="three">${Row.3}</span> welcome you. <span>${Hello.World}, this is a new world.</span></p>
</div>


If you cannot change the HTML, your best bet would be to make use of a regex.

The following regex will replace anything in the format ${...}:

var element = document.getElementById('div001');
var result = element.innerHTML.replace(/\${\S+}/gm, "REPLACED");
element.innerHTML = result;
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div id="div001">
  This is ${Row.1}.
  <p>${Row.2} explain something else.</p>
  <p>${Row.3} welcome you. <span>${Hello.World}, this is a new world.</span></p>
</div>

Upvotes: 1

CertainPerformance
CertainPerformance

Reputation: 371233

You can make a recursive function that iterates through all child nodes, and if they're text nodes, replaces their text - if they're element nodes, recursively call the function on them:

function replaceTextNodes(elm) {
  elm.childNodes.forEach((node) => {
    if (node.nodeType === 3) {
      // Text node:
      node.textContent = node.textContent.replace(/\${([^}]+)}/g, '$1');
    } else if (node.nodeType === 1) {
      // Element node, recurse:
      replaceTextNodes(node);
    }
  });
}
replaceTextNodes(document.querySelector('#div001'));
<div id="div001">
  This is ${Row.1}.
  <p>${Row.2} explain something else.</p>
  <p>${Row.3} welcome you. <span>${Hello.World}, this is a new world.</span></p>
</div>

Upvotes: 1

Related Questions