remove functions and attributes from html code

Viewed 371

Let's say we have a div as follows

<div id = "container" >
    <p contenteditable="false">Hello World</p>
    <button onclick="alert();"></button>
</div>

and we retrieved the content of the div and saved it into a variable

var content = document.getElementById("container").innerHTML;

Now we want to remove the contenteditable="false" and the onclick="alert();"

I have tried the following:

content = content.replace('contenteditable="false"','');
content = content.replace('onclick="alert();"','');

and then put the content back inside

document.getElementById("container").innerHTML = content;

but this did not work for me.

3 Answers

It's much easier to do it by cloning and then removing them from the clone before using innerHTML:

var content = cleanContent(document.getElementById("container").cloneNode(true)).innerHTML;

Where clean is something like:

function clean(elm) {
    for (const key in elm) {
        if (key.startsWith("on")) {
            elm.removeAttribute(key);
        }
    }
    elm.contentEditable = false;
    Array.from(elm.children).forEach(clean);
    return elm;
}

Live Example:

function clean(elm) {
    for (const key in elm) {
        if (key.startsWith("on")) {
            elm.removeAttribute(key);
        }
    }
    elm.contentEditable = false;
    Array.from(elm.children).forEach(clean);
    return elm;
}
var content = clean(document.getElementById("container").cloneNode(true)).innerHTML;
document.getElementById("container").innerHTML = content;
<div id="container">
<p contenteditable="false">Hello World</p>
<button onclick="alert('x');">Button</button>
</div>

This does exactly what you want. Get the content of the container and remove all the attributes, but as you can see it's a pretty messy solution. I recommend you use .removeAttr if the situation allows it. Converting the contents of an entire div into string and then replacing attributes with blank space is quite an unusual solution.

$(document).ready(function(){

    let content = document.getElementById("container").innerHTML
    let newContent = content.replace(/ contenteditable="false"| onclick="alert|\(|\)|;"/g , '')

    console.log("This is the old content:" + content)
    console.log("This is the new content:" + newContent)

    document.getElementById("container").innerHTML = newContent

})

Below is a much more simple solution that just removes the attributes when the document is ready, but I don't know if this is quite what you want.

$(document).ready(function(){

    $("#container").children().removeAttr("contenteditable onclick")

})

This is exactly what you requested but are you sure you want to have the option the separate the node? You could just target them directly.

const setup = () => {
    const container = document.getElementById("container");
  
  //setup changes
  const content = container.cloneNode(true);
  content.querySelector('p').removeAttribute('contenteditable');
  content.querySelector('button').removeAttribute('onclick');
  
  //apply changes
  container.innerHTML = content.innerHTML;
  }

window.addEventListener('load', setup);
<div id = "container" >
    <p contenteditable="false">Hello World</p>
    <button onclick="alert();"></button>
</div>

Related