Я пишу синтаксический ярлык. Маркер должен обновлять подсветку сразу при вводе текста и навигации с помощью клавиш со стрелками.Как получить позицию текстового курсора после события нажатия клавиши?
Проблема, с которой я сталкиваюсь, заключается в том, что при запуске события «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>
В примере, поместите курсор перед словом 'Foo', а затем нажмите → (ключ Стрелка вправо).
В консоли вашего любимого DevTool вы увидите следующее:
keydown 0
keypress 0
keyup 1
Это 0
, кроме keypress
, очевидно, старая каретки положения. Если зажать → немного больше, вы получите что-то вроде этого:
keydown 0
keypress 0
keydown 1
keypress 1
keydown 1
keypress 1
keydown 2
keypress 2
keyup 2
То, что я хочу, чтобы это новое положение каретки, как я хотел бы получить его «KeyUp» или «вход». Хотя «keyup» запускается слишком поздно (я хочу выделить синтаксис при нажатии клавиши), а «вход» запускается только при наличии некоторого ввода (но → не производит ввода).
Есть ли событие, которое было произведено после того, как позиция каретки изменилась, а не только на вход? Или мне нужно рассчитать положение текстового курсора, и если да, то как? (Я предполагаю, что это может быть довольно сложным, когда текст обтекает и нажимается ↓ (Стрелка вниз).)
Я думаю, у вас будет другая проблема с использованием события нажатия клавиши. Кажется, что Chrome не срабатывает при нажатии клавиши со стрелкой (Firefox делает). В статусе WontFix есть старая хромовая ошибка: https://bugs.chromium.org/p/chromium/issues/detail?id=2606 – Alex
Спасибо за подсказку! Правильно, событие 'keypress' не запускается, но [оно явно отмечено как устаревшее] (https://www.w3.org/TR/uievents/#legacy-keyboardevent-event-types), в любом случае. Как я увидел сейчас, в спецификации указано, что людям рекомендуется использовать событие 'beforeinput' вместо этого. И 'keydown' также запускается непрерывно. Хотя все эти события увольняются слишком рано. Теперь я [зарегистрировал проблему в спецификации пользовательских интерфейсов] (https://github.com/w3c/uievents/issues/111) в надежде получить соответствующее событие для этого. –
Позиции курсора/выбор и т. Д. Все еще являются лавашами для поддержки во всех браузерах. Это было какое-то время, когда мне было нужно это, но [rangy] (https://github.com/timdown/rangy) очень прост в работе с курсором. –