I am trying to read multi line user input on a content editable div, and I don't get the right number of line breaks when I read the input with contentEditableDiv.innerText
.
I tried textContent
, but it doesn't return any line break, while innerText
returns too many sometimes. innerHTML
doesn't seem appropriate since I don't want any HTML code, just text.
If my div
contains:
a
b
It returns "a↵b" (97 10 98
in the example)
But if my <div>
contains:
a
b
innerText
returns a↵↵↵b
(one too many ↵, 97 10 10 10 98
in the example)
var input = document.getElementById("input");
var button = document.getElementById("button");
var result = document.getElementById("result");
button.addEventListener("click", (event) => {
var charCodes = "";
for (var i = 0; i < input.innerText.length; ++i) {
charCodes += input.innerText.charCodeAt(i) + " ";
}
result.innerText = charCodes;
});
<div id="input" contenteditable="true" spellcheck="true" style="border:1px #000 solid"></div>
<button id="button">check</button>
<div id="result"></div>
The standard is a bit vague:
UAs should offer a way for the user to request an explicit line break at the caret position without breaking the paragraph, e.g. as the default action of a keydown event whose identifier is the "Enter" key and that has a shift modifier set. Line separators are typically found within a poem verse or an address. To insert a line break, the user agent must insert a br element.
If the caret is positioned somewhere where phrasing content is not allowed (e.g. in an empty ol element), then the user agent must not insert the br element directly at the caret position. In such cases the behavior is UA-dependent, but user agents must not, in response to a request to insert a line separator, generate a DOM that is less conformant than the DOM prior to the request.
To conform this definition, it is safe to wrap the <br>
element into <div>
, which Chrome does, but it is UA dependent, so you should not rely on this. The side effect on this behavior and the cause of your problem is that both div
and br
elements produces line break in the innerText
property.
The innerHTML
of a↵↵b
looks like this in Chrome:
a
<div>
<br>
<div>
<br>
<div>
b
</div>
</div>
</div>
But if you paste it (instead of typing char by char) it looks like this
<div>a</div>
<div>
<br>
</div>
<div>
<br>
</div>
<div>b</div>
To reduce the line breaks, you need to further process the innerHTML
and treat
<div><br></div>
after every input change as a single line-break and then read the innerText
(with caution on places where phrasing content like br
is not allowed, but in real life browsers can handle them well).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With