Emil Emil - 4 months ago 23
CSS Question

How to prevent a contenteditable div from rendering html?

Here is my code: https://jsfiddle.net/tb8ryyp6/1/

As you can see if we drag and drop image to contenteditable

div
its content is rendered as HTML. I want to prevent this behavior. Currently I solved this problem with attaching event handler to contenteditable
div
on drop event like this
ondrop='return false;'
.

This works for me.

<div contenteditable='true' ondrop='return false;'>


But. This solution seems not to be a cross-browser solution and user can remove this even handler easily at any time by changing HTML source code in dev-tools.

In general I want to prevent a contenteditable
div
from rendering any HTML element. This element could be not just image it could be an anchor element for example. As solution it can be both a cross-browser preventing of drop actions or showing HTML as text. But first one is preferable.

Thanks for your help!

Answer

In most cases, you can design a <textarea> just like anything else. But what you want can also be done with a <div contenteditable>.

user can remove this even handler at any time by changing html source code in dev-tools.

If you use addEventListener("drop", func), the event listener isn't visible in the html code. It can still be removed though, but then it's not your problem if the website doesn't work properly anymore (it's only changed in the browser, not on the server!)

This code uses the innerText property (which contains the unformatted text). Since line breaks are \n in innerText and <br> in the <div>, it has to be converted.

var ediv = document.getElementById("ediv");

function noHTML() {
    setTimeout(function() {
        var str1 = ediv.innerText.replace(/\n/g,"");
        var str2 = ediv.innerHTML.replace(/<br>/g,"");
        
        if (str1 != str2) {
            ediv.innerText = ediv.innerText;
        }
    }, 1);
}

// Remove markup when dropping something (e.g. image/ link)
ediv.addEventListener("drop", noHTML);
// Remove markup when pasting something (e.g. from Microsoft Word)
ediv.addEventListener("paste", noHTML);
// Remove markup from the clipboard when copying something
ediv.addEventListener("copy", function(e) {
    noHTML();
    if (e.clipboardData) {
        var text = window.getSelection().toString();
        e.preventDefault();
        e.clipboardData.setData('Text', text);
    }
});
// Remove markup when the div gains focus
ediv.addEventListener("focus", noHTML);
// Remove markup when the div loses focus
ediv.addEventListener("blur", noHTML);
#ediv{
  background-color: white;
  height: 70px;
  border: 2px dotted blue; 
  margin-bottom: 20px;
  padding: 10px;
}
[placeholder]:empty:before {
    content: attr(placeholder);
    color: #ddd; 
}
[placeholder]:empty:focus:before {
    content: "";
}
#img {
  text-align: center;
}
<div id='ediv' contenteditable='true' placeholder='i am contenteditable div..'></div>

<div id='img'>
  <span>drag and drop this image to contenteditable div</span>
  <br>
  <img src='https://upload.wikimedia.org/wikipedia/commons/4/4d/Cat_March_2010-1.jpg' width='220px'><br>
  <a href='https://upload.wikimedia.org/wikipedia/commons/4/4d/Cat_March_2010-1.jpg'>Hyperlink</a>
</div>

Updated Fiddle

Comments