Es importante para mí saber la diferencia entre hacer clic antes de una letra y después de la anterior, aunque ambos casos pueden verse iguales en la pantalla. Esto se debe a que el significado se puede transmitir a través del número de tramos anidados. Un ejemplo:
<span id="x-container"><span id="x">x</span></span><span id="y">y</span> <script> document.addEventListener('selectionchange', e => { var selection = window.getSelection(); if (selection.type =='Caret') console.log(selection.anchorNode.textContent,selection.anchorOffset) }) </script>Los console.log() se ven de la siguiente manera:
haciendo clic en la x ligeramente a la izquierda del centro, obtenemos x 0 (correcto)
haciendo clic en la x ligeramente a la derecha del centro, obtenemos x 1 (correcto)
Al hacer clic en la y ligeramente a la izquierda del centro, obtenemos x 1 nuevamente: ¡¡¡MAL!!!!
haciendo clic en y ligeramente a la derecha del centro, obtenemos y 1 (correcto)
¿Cómo puedo solucionar este tercer caso para saber si hicimos clic antes de y o después de x? Intenté agregar un tramo ficticio entre los dos, pero no funcionó.
Tenga en cuenta que x e y se ven un poco cerca uno del otro aquí. En lo que estoy haciendo, estoy agregando relleno para que no se vea tan extraño y sea más fácil hacer clic antes de y que después de x. Solo confíe en mi palabra de que agregar relleno/margen no cambia el problema ...
Dado que solo está interesado en los eventos de cambio de selección que fueron activados por un evento del mouse, puede verificar qué elemento recibió el evento mousedown que activó este evento de cambio de selección.
Solo tiene que almacenarlo en una variable accesible para su controlador de cambio de selección, luego, si no es el nodo de anclaje de la anchorNode , o no lo contiene, sabrá que el navegador se equivocó.
Luego, debe verificar si el objetivo real estaba antes o después para encontrar correctamente el nuevo anchorOffset :
let activeElem = null; document.addEventListener('selectionchange', e => { const selection = window.getSelection(); let { anchorNode, anchorOffset } = selection; if (anchorNode === selection.focusNode) { if (activeElem && (!activeElem.contains(anchorNode))) { const isBefore = activeElem.nextElementSibling.contains(anchorNode); anchorOffset = isBefore ? activeElem.textContent.length : 0; anchorNode = activeElem; } console.log(anchorNode.textContent, anchorOffset); } }) document.addEventListener("mousedown", e => // here you can change the selector from "span" to anything more restrictive // as long as it matches your "targetted" elements activeElem = e.target.matches("span") ? e.target : null ); document.addEventListener("mouseup", e => activeElem = null); <span id="x">x</span><span id="b">b</span>