1UnitedPower: Position von Textcursor ermitteln und setzen

Beitrag lesen

Hakuna matata!

Wenn man aber das innerHTML des div-Elements verändert, springt der Textcursor immer automatisch an den Anfang, was selbstverständlich unerwünscht ist.

innerHTML ist dein eigentliches Problem. Mit innerHTML ersetzt du nämlich einen Teilbaum durch einen komplett neuen Teilbaum. Selbst in dem einfachen Fall, dass die beiden Bäume exakt die selbe Struktur haben, sind das zwei völlig verschiedene Bäume. DOMKnoten haben diverse Zustände, dazu zählen zum Beispiel registrierte EventHandler, MicroData und ganz besonders wichtig eine sogenannte Identität (damit meine ich nicht das id-Attribut, sondern die Objekt-Identität). Mit innerHTML gehen all diese Zustände des alten Baums verloren, ein Beispiel:

<div id="outer"><div id="inner"></div></div>


var inner1 = document.getElementById('outer');
var outer = document.getElementById('inner');

outer.innerHTML = '<div id="inner"></div>';
// Augenscheinlich haben wir dadurch nichts verändert, aber der Schein trügt

var inner2 = document.getElementById('inner');

console.assert( inner1 === inner2 );
// Error: Assertion failed

Die Selection-API arbeitet aber mit genau diesen Objekt-Identitäten, selbst wenn du in der Lage wärst, die Cursor-Position vor der Ersetzung mit innerHTML auszulesen, dann könntest du sie nach Ersetzung niemals wieder dort einfügen, wo sie intuitiv betrachtet hingehörte, weil der neue Baum ganz neue Objekt-Identitäten hat.

Du willst innerHTML deshalb unbedingt vermeiden und stattdessen ein inkrementelles Update auf dem DOMBaum ausführen, sodass nur die Bereiche ausgetauscht werden, die wirklich von Änderung betroffen sind. Wenn sich nur ein Attribut ändert, dann muss man nicht gleich das ganze Element austauschen, man muss nichtmal den Attribut-Knoten austauschen, es reicht dem alten Attribut einen neuen Wert zu verpassen. Wenn dir das gelingt, dann hat sich dein Problem mit dem Cursor übrigens von selbst erledigt.

--
“All right, then, I'll go to hell.” – Huck Finn