1

I want to remove "Text" in an <li>.

Here's my attempt:

window.onload = function() {
  var str = document.getElementsByClassName("slide-2")[0].innerHTML; 
  var res = str.replace("Text", "Hello");
  document.getElementsByClassName("slide-2")[0].innerHTML = res;
}
<ul class="box1">
    <li class="slide-1">001</li>
    <li class="slide-2"><div data-rel="Text" class="slide-2"><img src=".."></div>Text</li>
    <li class="slide-3">003</li>
</ul>

<ul class="box2">
    <li class="slide-1">001</li>
    <li class="slide-2"><div data-rel="Text" class="slide-2"><img src=".."></div>Text</li>
    <li class="slide-3">003</li>
</ul>

It does not work because "data-rel" has the same value as the text that I want to remove.

I can't change or remove the value in "data-rel".

ggorlen
  • 44,755
  • 7
  • 76
  • 106
  • [This library](https://github.com/padolsey/findAndReplaceDOMText) may help. – CherryDT Aug 14 '20 at 15:56
  • Does this answer your question? [Find and replace specific text characters across a document with JS](https://stackoverflow.com/questions/18643766/find-and-replace-specific-text-characters-across-a-document-with-js) - In particular [this answer](https://stackoverflow.com/a/50835546/1871033) may be useful. – CherryDT Aug 14 '20 at 15:57

5 Answers5

0

You can use nodeValue to set the text content of your nodes without disrupting other child elements.

const node = document.querySelector("li.slide-2").childNodes[1];
node.nodeValue = node.nodeValue.replace(/Text/g, "Hello");

const dataset = document.querySelector("div.slide-2").dataset;
console.log("is the `data-rel` attribute still `Text`?", dataset);
<ul class="box1">
    <li class="slide-1">001</li>
    <li class="slide-2"><div data-rel="Text" class="slide-2"><img src=".."></div>Text</li>
    <li class="slide-3">003</li>
</ul>

<ul class="box2">
    <li class="slide-1">001</li>
    <li class="slide-2"><div data-rel="Text" class="slide-2"><img src=".."></div>Text</li>
    <li class="slide-3">003</li>
</ul>

Or, if you want to replace multiple occurrences:

for (const node of [...document.querySelectorAll("li.slide-2")]) {
  const child = node.childNodes[node.childNodes.length-1];
  child.nodeValue = child.nodeValue.replace(/Text/g, "Hello");
}
<ul class="box1">
    <li class="slide-1">001</li>
    <li class="slide-2">
      <div data-rel="Text" class="slide-2">
        this Text won't be touched... 
      </div>
      Text and some more Text text.
    </li>
    <li class="slide-3">003</li>
</ul>

<ul class="box2">
    <li class="slide-1">001</li>
    <li class="slide-2">
      <div data-rel="Text" class="slide-2">
        this Text also won't be touched... 
      </div>
      Text
    </li>
    <li class="slide-3">003</li>
</ul>

Consider using /\bText\b/g if you want to enforce word boundaries and disregard Textual.

Applying the slide-2 class name to both the child <div> and parent <li> may be a potential antipattern.

ggorlen
  • 44,755
  • 7
  • 76
  • 106
0

var str = document.getElementsByClassName("slide-2")[0].innerHTML; 
      var res = str.replace(/Text/gi, "Hello");
      document.getElementsByClassName("slide-2")[0].innerHTML = res;
<ul class="box1">
    <li class="slide-1">001</li>
    <li class="slide-2"><div data-rel="Text" class="slide-2"><img src=".."></div>Text</li>
    <li class="slide-3">003</li>
</ul>

<ul class="box2">
    <li class="slide-1">001</li>
    <li class="slide-2"><div data-rel="Text" class="slide-2"><img src=".."></div>Text</li>
    <li class="slide-3">003</li>
</ul>
sazzad
  • 505
  • 4
  • 5
0

Select the childNodes, loop over and find text node (3) with the text you want to match.

window.onload = function() {
  var lis = document.getElementsByClassName("slide-2");
  Array.from(lis).forEach(function(li) {
    var textNode = Array.from(li.childNodes).find(function(node) {
      // return node.nodeType == 3;
      return node.nodeType == 3 && node.nodeValue === "Text";
    })
    // if (textNode) textNode.nodeValue = "";
    if (textNode) textNode.remove();
  })
}
<ul class="box1">
  <li class="slide-1">001</li>
  <li class="slide-2">
    <div data-rel="Text" class="slide-2"><img src=".."></div>Text</li>
  <li class="slide-3">003</li>
</ul>

<ul class="box2">
  <li class="slide-1">001</li>
  <li class="slide-2">
    <div data-rel="Text" class="slide-2"><img src=".."></div>Text</li>
  <li class="slide-3">003</li>
</ul>
epascarello
  • 204,599
  • 20
  • 195
  • 236
0

i just add a new div with the same class name after image, but hey its working XD

window.onload = function() {
  var count = document.getElementsByClassName("slide-2").length; 
  for(var i=0;i<count;i++){
    if(document.getElementsByClassName("slide-2")[i].innerHTML == "Text"){
    document.getElementsByClassName("slide-2")[i].innerHTML = "Hello";  
    }
  } 
}
<ul class="box1">
    <li class="slide-1">001</li>
    <li class="slide-2"><div data-rel="Text" class="slide-2"><img src=".."></div><div class="slide-2">Text</div></li>
    <li class="slide-3">003</li>
</ul>

<ul class="box2">
    <li class="slide-1">001</li>
    <li class="slide-2"><div data-rel="Text" class="slide-2"><img src=".."></div><div class="slide-2">Text</div></li>
    <li class="slide-3">003</li>
</ul>
ucup
  • 665
  • 6
  • 17
-1

what about splitting

str = str.split('</div>');
str[1] = 'Hello';
let res = str.join('</div>');
Mustafa Reda
  • 179
  • 5