Поскольку это заняло у меня целую вечность, чтобы понять, как использовать новый API window.getSelection, я собираюсь поделиться им для потомков. Обратите внимание, что MDN предлагает более широкую поддержку window.getSelection, однако ваш опыт может отличаться.
const getSelectionCaretAndLine = () => {
// our editable div
const editable = document.getElementById('editable');
// collapse selection to end
window.getSelection().collapseToEnd();
const sel = window.getSelection();
const range = sel.getRangeAt(0);
// get anchor node if startContainer parent is editable
let selectedNode = editable === range.startContainer.parentNode
? sel.anchorNode
: range.startContainer.parentNode;
if (!selectedNode) {
return {
caret: -1,
line: -1,
};
}
// select to top of editable
range.setStart(editable.firstChild, 0);
// do not use 'this' sel anymore since the selection has changed
const content = window.getSelection().toString();
const text = JSON.stringify(content);
const lines = (text.match(/\\n/g) || []).length + 1;
// clear selection
window.getSelection().collapseToEnd();
// minus 2 because of strange text formatting
return {
caret: text.length - 2,
line: lines,
}
}
Вот jsfiddle, который запускается при нажатии клавиши . Однако обратите внимание, что быстрое нажатие клавиш со стрелками, а также быстрое удаление, похоже, являются пропущенными событиями.