There is a non-standard user-modify
CSS property which is supported by WebKit-based browsers:
-webkit-user-modify: read-write-plaintext-only;
This eliminates the need to use deprecated execCommand
API or error-prone steps to position caret correctly.
[contenteditable] {
-webkit-user-modify: read-write-plaintext-only;
}
<div><p style="color:red">Copy <em>this</em> <u>styled</u> text</p></div>
<div contenteditable="true">into this editable element</div>
There is one strange behavior: copy-and-paste text selected via double-click may introduce extra leading and/or trailing whitespaces (on macOS at least).
To support non-WebKit browsers, you still need to listen to paste
event, such as:
someEditableElement.addEventListener("paste", function (e) {
e.preventDefault();
const text = e.clipboardData ? e.clipboardData.getData("text/plain") : "";
if (document.queryCommandSupported?.("insertText")) {
return document.execCommand("insertText", false, text);
}
const selection = document.getSelection();
if (!selection) return;
const range = selection.getRangeAt(0);
range.deleteContents();
range.insertNode(new Text(text));
range.collapse(); // select nothing
selection.removeAllRanges(); // position caret after inserted text
selection.addRange(range); // show caret
});
There are differences between these two approaches. Use your discretion.