Search code examples
javascriptjqueryhtmlregex

How can I remove all tag's attributes except specific ones?


I have this string:

var str = '<p>paragraph<a>link</a></p>
           <div class="myclass">
               <div>something</div>
               <div style="mystyle">something</div>
               <b><a href="#">link</a></b>
               <b><a href="#" name="a name">link</a></b>
               <b style="color:red">bold</b>
               <img src="../path" alt="something" />
               <img src="../path" alt="something" class="myclass" />
           </div>';

I want to remove all attributes except href, src, alt. So this is expected result:

/* 
<p>paragraph<a>link</a></p>
<div>
    <div>something</div>
    <div>something</div>
    <b><a href="#">link</a></b>
    <b><a href="#">link</a></b>
    <b>bold</b>
    <img src="../path" alt="something">
    <img src="../path" alt="something">
</div>

How can I do that?


I can just select them which isn't useful:

/<[a-z]+ .*?(href|src|alt)="[^"]+"/g


Solution

  • We need to remove the attribute from the end.

    Please note that you need backticks to quote a string with embedded newlines

    var str = `<p>paragraph<a>link</a></p>
               <div class="myclass">
                   <div>something</div>
                   <div style="mystyle" class="someclass">something</div>
                   <b><a href="#">link</a></b>
                   <b><a href="#" name="a name">link</a></b>
                   <b style="color:red">bold</b>
                   <img src="../path" alt="something" />
                   <img src="../path" alt="something" class="myclass" />
               </div>`;
    var div = document.createElement("div");
    div.innerHTML=str;
    div.querySelectorAll("*").forEach(function(el){
      for (let atts = el.attributes, i = atts.length-1; i >=0; i--) { // remove from the end
        var att = atts[i].nodeName;
        if (["src","alt","href"].indexOf(att) ==-1) el.removeAttribute(att); 
      }
    }); 
    // console.log(div); alert shows it more clearly
    alert(div.innerHTML);