简体   繁体   中英

removing tag name but keep tag

Hello I have a <strong></strong> Tag nested in a paragraph <p></p> , I'm trying to remove the <strong> tag but keep the text or the value. Something similar to unwrapping in jquery but in javascript.

I tried this code on a dummy HTML page and it works fine

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

But as soon as I try the same code on a real page example: https://www.bustle.com/privacy

I get this error:

Failed to execute 'replaceChild' on 'Node': The node to be replaced is not a child of this node.

Any idea on how to get this to work on the example or any other example?

getElementsByTagName() returns a live NodeList. So when you replace a tag, the indexes of all the following elements shift down and the code fails when you have more than one <strong> tag in the same paragraph. As a result, it will skip some tags.

The solution is to convert the NodeList to an array so it doesn't change while you're looping.

Another problem in your real page that isn't in the snippet is that the <strong> tags can be nested deeply within the <p> . You should use strongs[j].parentElement to get its direct parent, rather than assuming that the p[i] is the 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>

You can also avoid the nested loops by using a query selector.

 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>

No need to loop through paragraphs to remove <strong> . Simply removing all 'strongs' in place works fine.

 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>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM