Ich schreibe einen Syntax-Highlighter. Der Highlighter sollte die Hervorhebung sofort bei der Texteingabe und Navigation mit den Pfeiltasten aktualisieren.Wie bekomme ich die Position des Textcursors nach dem Tastendruck?
Das Problem, mit dem ich konfrontiert bin, ist, dass, wenn das 'keypress' Ereignis ausgelöst wird, Sie immer noch die alte Position des Textcursors über window.getSelection()
erhalten.
Beispiel:
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>
Im Beispiel setzen die Einfügemarke vor dem Wort 'foo', dann → (die rechte Pfeiltaste) drücken.
Innerhalb der Konsole Ihres Lieblings DevTool Sie folgenden sehen werden:
keydown 0
keypress 0
keyup 1
Die 0
neben keypress
ist offensichtlich die alte Position der Einfügemarke. Wenn Sie ein wenig nach unten → länger halten, werden Sie so etwas wie dieses:
keydown 0
keypress 0
keydown 1
keypress 1
keydown 1
keypress 1
keydown 2
keypress 2
keyup 2
Was ich will bekommen, ist die neue Position der Einfügemarke, wie ich es für ‚keyup‘ bekommen würde oder ‚Input‘. Obwohl "keyup" zu spät ausgelöst wird (ich möchte die Syntax hervorheben, während die Taste gedrückt wird) und "input" nur ausgelöst wird, wenn tatsächlich ein Eingang vorhanden ist (→ erzeugt jedoch keine Eingabe).
Gibt es ein Ereignis, das ausgelöst wird, nachdem sich die Caret-Position geändert hat und nicht nur bei der Eingabe? Oder muss ich die Position des Textcursors berechnen und wenn ja, wie? (Ich nehme an, dies ziemlich kompliziert werden kann, wenn der Text umbrochen und Sie drücken ↓ (die Pfeiltaste nach unten).)
Ich denke, Sie werden ein anderes Problem mit dem Tastendruck-Ereignis haben. Chrome scheint das Ereignis nicht auszulösen, wenn eine Pfeiltaste gedrückt wird (Firefox tut das). Es gibt einen alten Chrombug im Status WontFix, der dies beschreibt: https://bugs.chromium.org/p/chromium/issues/detail?id=2606 – Alex
Vielen Dank für den Hinweis! Richtig, das 'keypress'-Ereignis wird nicht ausgelöst, aber [es ist offensichtlich als veraltet gekennzeichnet] (https://www.w3.org/TR/uievents/#legacy-keyboardevent-event-types), wie auch immer. Wie ich jetzt gesehen habe, heißt es in der Spezifikation, dass Leuten empfohlen wird, stattdessen das 'BeforeInput'-Ereignis zu verwenden. Und "Keydown" wird auch kontinuierlich abgefeuert. Obwohl all diese Ereignisse zu früh gefeuert werden. Ich habe jetzt ein Problem in der UI-Events-Spezifikation (https://github.com/w3c/uievents/issues/111) in der Hoffnung, ein passendes Event dafür zu bekommen, eingereicht. –
Cursorpositionen/Auswahl usw. sind immer noch eine Pita, die auf allen Browsern unterstützt wird. Es ist eine Weile her, dass ich das brauchte, aber [riggy] (https://github.com/timdown/rangy) ist sehr solide mit cursor-verwandten Sachen .. –