Bonjour j'ai une balise <strong></strong> imbriquée dans un paragraphe <p></p>, j'essaye de supprimer la balise <strong> mais je garde le texte ou la valeur. Quelque chose de similaire au déroulement en jquery mais en javascript.

J'ai essayé ce code sur une page HTML factice et cela fonctionne bien

<html>
<body>
    <p>aaa <Strong>bbbbb</Strong></p>
    <p>acccaa <Strong>ddddd</Strong></p>
    <p>eeee <Strong>ffff</Strong></p>

    <script>
        var p = document.getElementsByTagName("p");
        for(var i=0;i<p.length;i++){
            var strongs = p[i].getElementsByTagName("strong");
            for(var j=0;j<strongs.length;j++){
                p[i].replaceChild(document.createTextNode(strongs[j].innerText),strongs[j]);
            }
        }
    </script>
</body>
</html>

Mais dès que j'essaye le même code sur un exemple de page réelle: https://www.bustle.com/privacy

Je reçois cette erreur:

Échec de l'exécution de 'replaceChild' sur 'Node': le nœud à remplacer n'est pas un enfant de ce nœud.

Une idée sur la façon de faire fonctionner cela sur l'exemple ou sur tout autre exemple?

0
Troy 20 avril 2020 à 18:53

3 réponses

Meilleure réponse

getElementsByTagName() renvoie une liste de nœuds live . Ainsi, lorsque vous remplacez une balise, les index de tous les éléments suivants sont décalés vers le bas et le code échoue lorsque vous avez plusieurs balises <strong> dans le même paragraphe. En conséquence, il sautera certaines balises.

La solution est de convertir le NodeList en tableau pour qu'il ne change pas pendant que vous faites une boucle.

Un autre problème dans votre page réelle qui n'est pas dans l'extrait de code est que les balises <strong> peuvent être imbriquées profondément dans <p>. Vous devriez utiliser strongs[j].parentElement pour obtenir son parent direct, plutôt que de supposer que p[i] est le parent.

var p = document.getElementsByTagName("p");
for (var i = 0; i < p.length; i++) {
  var strongs = Array.from(p[i].getElementsByTagName("strong"));
  for (var j = 0; j < strongs.length; j++) {
    strongs[j].parentElement.replaceChild(document.createTextNode(strongs[j].innerText), strongs[j]);
  }
}
<html>

<body>
  <p>aaa
    <Strong>bbbbb</Strong> - <strong>12345</strong></p>
  <p>acccaa <span><Strong>ddddd</Strong> x</span></p>
  <p>eeee
    <Strong>ffff</Strong>
  </p>

</body>

</html>

Vous pouvez également éviter les boucles imbriquées en utilisant un sélecteur de requête.

var strongs = document.querySelectorAll("p strong");
strongs.forEach(strong => strong.parentElement.replaceChild(document.createTextNode(strong.innerText), strong));
<html>

<body>
  <p>aaa
    <Strong>bbbbb</Strong> - <strong>12345</strong></p>
  <p>acccaa <span><Strong>ddddd</Strong> x</span></p>
  <p>eeee
    <Strong>ffff</Strong>
  </p>

</body>

</html>
0
Barmar 20 avril 2020 à 16:10

Pas besoin de parcourir les paragraphes pour supprimer <strong>. Le simple fait de supprimer tous les «forts» en place fonctionne très bien.

function removeStrongs() {
  let strongs = document.querySelectorAll('strong');
  strongs.forEach(strong => {
    strong.insertAdjacentText('afterend', strong.innerText);
    strong.remove();
  });
}
<h4>This is a <strong>Title</strong></h4>
<p>
  Now is the time for all <strong>good</strong> men to come to the <strong>aid</strong> of the party.
</p>
<p>A <strong>quick brown</strong> fox jumps over the lazy dog.</p>

<button onclick="removeStrongs();">Remove Strongs</button>
0
terrymorse 20 avril 2020 à 16:28

Voici une approche plus moderne:

{
  [...document.querySelectorAll("p")] // all <p> (to Array)
  .forEach(p => [...p.querySelectorAll("strong")] // all <strong> within <p> (to Array)
    .forEach(s => {
      // replace <strong> with its text
      s.parentNode
        .replaceChild(
          document.createTextNode(`[Text from Strong: ${s.textContent}]`), s );
    }));
}
<p>aaa
  <Strong>bbbbb</Strong> Hello
</p>
<p>acccaa
  <Strong>ddddd</Strong> World
</p>
<p>eeee
  <Strong>ffff</Strong>!
</p>
0
KooiInc 20 avril 2020 à 16:16