Как получить позицию текстового курсора после события нажатия клавиши?
Я пишу синтаксический ярлык. Маркер должен обновлять подсветку сразу при вводе текста и навигации с помощью клавиш со стрелками.
Проблема, с которой я сталкиваюсь, заключается в том, что при запуске события "keypress" вы все равно получаете старую позицию текстового курсора через window.getSelection()
.
Пример:
function handleKeyEvent(evt) {
console.log(evt.type, window.getSelection().getRangeAt(0).startOffset);
}
var div = document.querySelector("div");
div.addEventListener("keydown", handleKeyEvent);
div.addEventListener("keypress", handleKeyEvent);
div.addEventListener("input", handleKeyEvent);
div.addEventListener("keyup", handleKeyEvent);
<div contenteditable="true">f<span class="highlight">oo</span></div>
Ответы
Ответ 1
Вы можете использовать setTimeout
для обработки события keydown
асинхронно:
function handleKeyEvent(evt) {
setTimeout(function () {
console.log(evt.type, window.getSelection().getRangeAt(0).startOffset);
}, 0);
}
var div = document.querySelector("div");
div.addEventListener("keydown", handleKeyEvent);
<div contenteditable="true">This is some text</div>
Ответ 2
Здесь решение, исправляющее позицию с использованием события "keydown":
function handleKeyEvent(evt) {
var caretPos = window.getSelection().getRangeAt(0).startOffset;
if (evt.type === "keydown") {
switch(evt.key) {
case "ArrowRight":
if (caretPos < evt.target.innerText.length - 1) {
caretPos++;
}
break;
case "ArrowLeft":
if (caretPos > 0) {
caretPos--;
}
break;
case "ArrowUp":
case "Home":
caretPos = 0;
break;
case "ArrowDown":
case "End":
caretPos = evt.target.innerText.length;
break;
default:
return;
}
}
console.log(caretPos);
}
var div = document.querySelector("div");
div.addEventListener("keydown", handleKeyEvent);
div.addEventListener("input", handleKeyEvent);
<div contenteditable="true">f<span class="highlight">oo</span></div>