How to prevent browser from inserting HTML into a contenteditable element

8.3k views Asked by At

When a user inserts linebreaks in a contenteditable element, browsers insert HTML into the element.

Here is what you get when you hit [Enter] in various browsers:

IE:      <p></p>
Chrome:  <div><br></div>
Safari:  <div><br></div>
Firefox: <br />
Opera:   <br />

(Test for yourself with this JSFiddle demo.)

Is there a way to get the browser NOT to insert HTML when the user hasn't inserted any HTML? Of course, I could just use

<textarea></textarea>

...and that does behave very similar to how I want, however, I don't want a strictly "text-only" input, as I will be adding and modifying HTML in the editable element using Javascript.

I considered constantly stripping all HTML out as the user types, only allowing HTML with a special class that I create to remain. That doesn't seem like a great solution, however. Is there something like wrap='soft' or some other way to say "stop making up HTML and putting it in my element!"

2

There are 2 answers

1
AudioBubble On

If you make it content editable, you are implicitly allowing the user to change the content of the HTML.

Pressing return should insert some kind of newline - either as closing a paragraph (</p>) and starting a new one (<p>), or entering a line break (<br>). Both of which in HTML require HTML tags, for the simple fact that a standard newline character (eg. \n or \n\r) is rendered as a single space, which is not what the user would expect - so inserting a raw newline as a "soft wrap" would not make sense and will ultimately lead to users impotently slamming their enter key getting mad at your site for not inserting a break when they think it should.

An even more fun fact is that if a user highlights some text, they can (or should) be able to bold and italicize text using keyboard shortcuts, which will again insert HTML.

Short of writing Javascript to override this behaviour, I am not sure you can disable the enter key inserting HTML tags to render the requested newlines.

To demonstrate this, here is a really simple page:

<html>
<body>
<div contentEditable="true"> Some things.</div>
</body>
</html>

(In Internet Explorer at least) If you double click on the text it becomes editable. Move to the end of line and type the following:

  • Enter - ( A new paragaph is made (wrapping the prior text in p tags).
  • Type "Words", the select it and hit Crtl + b - the text is now wrapped in <strong> tags.
  • Hit Shift + Enter - a line break (<br>) is now inserted.
  • Type "More words", select it and hit Crtl + i Its now italicised in <em> tags.

And the source should look like:

<html>
<body>
<div contentEditable="true">
  <p>Some things.</p>
  <p>
    <strong>Words</strong>
    <br>
    <em>More words</em>
  </p>
</div>
</body>
</html>

If you want complete control over the content going into the area, I'd recommend using a WYSIWYG editor, or alternative, accept that the browser probably knows what its doing and let it do its thing so you don't need to worry about it.

4
kuroi neko On

There is no cross-browser way of disabling or forcing an editable div to interpret enter keypress differently from what the browser intended.

Besides, different browsers will do different things with the new line. Some will wrap lines inside <p> tags, some will add <br>.

The idea is that it's the browser that controls the editable div, not you.
If you try to fiddle with the output in real time, you will be like a passenger occasionally trying to snatch the wheel from the driver's hands.

You're not even guaranteed to get the key events from such a div. For instance, your fiddle does not seem to work in IE11.

I would rather do it just like this very SO editor does: use a textarea for user input and generate whatever rich HTML you want in another, non-editable div.