ContentEditable in Firefox creates 2 newlines instead of 1
This appears to be a bug with Firefox's implementation of innerText.
New lines in contenteditable
historically had a lack of consensus on the precise implementation. Gecko inserted <br>
s, IE and Opera's Presto wrapped the line in <p>
tags, and Webkit and Blink wrapped the line in <div>
tags. With its old implementation that used <br>
tags, Firefox's innerText
worked just fine, exactly how your question wants it to.
However today's modern browsers have reached a general consensus for the sake of consistency. Specifically for Firefox, MDN stated:
As of Firefox 60, Firefox will be updated to wrap the separate lines in
<div>
elements, matching the behavior of Chrome, modern Opera, Edge, and Safari.
When modern browsers insert an empty new line, they do so by wrapping a <br>
in <div>
tags. It seems that Firefox's innerText
implementation is interpreting this as two new lines.
A workaround is quite simple. The execCommand
method (unofficial W3 draft but supported by Firefox which is all we need) allows you to manipulate a contenteditable
's content with defined commands. One such command is defaultParagraphSeparator
, which allows you to specify whether to use <div>
or <p>
as the container for lines in your contenteditable
.
Firefox - and only Firefox - has additionally implemented support for <br>
s with defaultParagraphSeparator
. With this command the contenteditable behaves like it would have prior to FF60, that is, inserting line breaks instead of wrapping lines within a container.
Thus, all you need to do is put:
document.execCommand("defaultParagraphSeparator", false, "br");
in your JavaScript. All versions of Firefox will then be using <br>
s instead of containers for new lines in contenteditable
, thus making innerText
correctly interpret new lines. And every browser other than Firefox will ignore it.
Trigger event on new line in content editable div
The other answers so far discussed monitoring the events that create a newline within a content editable div. However from the efforts so far it seems that this is not a reliable way to monitor if the user has brought the caret at a new line.
Despite concerns that having a setInterval event is clunky and adding to overhead, perhaps this is just my perception. I've tested the below in Firefox and Chrome on OSX.
function getNewLines() { console.log(document.getSelection()); if (document.getSelection().anchorNode) { var node = document.getSelection().anchorNode; var nodeContents = ""; if (node.innerHTML) { nodeContents = node.innerHTML.toLowerCase(); } else { nodeContents = node.innerHTML; } if (nodeContents !== undefined) { if (nodeContents === "" || nodeContents == "<br>" || nodeContents == "<br/>" || nodeContents.substr(nodeContents.length - 5) == "<br/>" || nodeContents.substr(nodeContents.length - 4) == "<br>") { console.log("you are on a new line :]"); } else { console.log('nope not a new line'); } } else { console.log('nice try, but no not a new line'); } }}setInterval(getNewLines, 100);
<div contenteditable="true"> <p>Lets get started!</p></div>
Why won't trailing newline character (\n) show empty line in content editable div?
I didn't quite get an answer to this problem (not just on SO but even in my research). However, I found a hack to get around this. Using one of the non breaking spaces characters gives me what I want. I don't intend to pass the data to third party processing, so whatever character I choose can be removed in post processing.
Related Topics
How to Remove The Arrows from Input[Type="Number"] in Opera
Do We Need Type="Text/CSS" for <Link> in HTML5
CSS Customization in a Bookdown Document
IE8 Playing Funny with List-Style-Position: Inside
Div Table-Cell Vertical Align Not Working
Styling HTML and Body Selector to Height: 100%; Vs Using 100Vh
There Is a 4Px Gap Below Canvas/Video/Audio Elements in HTML5
Syntax Highlighting in Jekyll Using Redcarpet
CSS: How to Align Vertically a "Label" and "Input" Inside a "Div"
How to Make The Overflow CSS Property Work with Hidden as Value
How to Create Responsive Text on Top of an Image
Horizontal Scroll in Div with Many Small Div's Inside (No Text)
Why Is My Content Showing Outside The Div
How to Push a Footer to The Bottom of Page When Content Is Short or Missing
Can Someone Explain to Me Why Clear:Both and Margin-Top Cannot Work in The Same Div
Jekyll Syntax Highlighting Not Working - Classes Are Not Being Added