Busco una solución definitiva de navegador cruzado para establecer la posición del cursor / cursor en la última posición conocida cuando un contentEditable = 'on' <div> recupera el foco. Parece que la funcionalidad predeterminada de un div editable de contenido es mover el cursor / cursor al comienzo del texto en el div cada vez que hace clic en él, lo que no es deseable.
Creo que tendría que almacenar en una variable la posición actual del cursor cuando dejan el foco del div, y luego volver a configurarlo cuando vuelvan a enfocar, pero no he podido juntar o encontrar un trabajo código de muestra todavía.
Si alguien tiene alguna idea, fragmentos de código de trabajo o muestras, me encantaría verlos.
Realmente todavía no tengo ningún código, pero esto es lo que tengo:
<script type="text/javascript">
// jQuery
$(document).ready(function() {
$('#area').focus(function() { .. } // focus I would imagine I need.
}
</script>
<div id="area" contentEditable="true"></div>
PD. He probado este recurso pero parece que no funciona para un <div>. Quizás solo para textarea ( Cómo mover el cursor al final de una entidad contentable )
contentEditable
trabajaba en los navegadores no-IE O_ORespuestas:
Esto es compatible con los navegadores basados en estándares, pero probablemente fallará en IE. Lo estoy proporcionando como punto de partida. IE no es compatible con DOM Range.
fuente
cursorStart.appendChild(document.createTextNode('\u0002'));
Es un reemplazo razonable, creemos. para el - char. Gracias por el códigoEsta solución funciona en todos los principales navegadores:
saveSelection()
se adjunta a los eventosonmouseup
yonkeyup
del div y guarda la selección en la variablesavedRange
.restoreSelection()
se adjunta alonfocus
evento del div y vuelve a seleccionar la selección guardada ensavedRange
.Esto funciona perfectamente a menos que desee que se restaure la selección cuando el usuario hace clic en el div también (lo cual es un poco poco intuitivo, ya que normalmente espera que el cursor vaya donde hace clic, pero el código está incluido para completar)
Para lograr esto, los eventos
onclick
yonmousedown
son cancelados por la funcióncancelEvent()
que es una función de navegador cruzado para cancelar el evento. LacancelEvent()
función también ejecuta larestoreSelection()
función porque a medida que se cancela el evento de clic, el div no recibe el foco y, por lo tanto, no se selecciona nada a menos que se ejecute esta función.La variable
isInFocus
almacena si está enfocada y se cambia a "falso"onblur
y "verdadero"onfocus
. Esto permite que los eventos de clic se cancelen solo si el div no está enfocado (de lo contrario, no podría cambiar la selección).Si desea que la selección se cambie cuando el div se enfoca con un clic y no se restaura la selección
onclick
(y solo cuando se le da foco al elemento mediante programacióndocument.getElementById("area").focus();
o similar, simplemente elimine los eventosonclick
yonmousedown
. Elonblur
evento y las funcionesonDivBlur()
ycancelEvent()
También se puede eliminar de forma segura en estas circunstancias.Este código debería funcionar si se deja caer directamente en el cuerpo de una página html si desea probarlo rápidamente:
fuente
if (window.getSelection)...
solo probará si el navegador admitegetSelection
, no si hay o no una selección?getSelection
API estándar o ladocument.selection
API heredada utilizada por versiones anteriores de IE. LagetRangeAt (0)
llamada posterior volveránull
si no hay una selección, que se verifica en la función de restauración.else if (document.createRange)
) es lo que estoy viendo. Solo se llamará siwindow.getSelection
no existe, pero usawindow.getSelection
window.getSelection
pero nodocument.createRange
, lo que significa que el segundo bloque nunca se usaría ...Actualizar
He escrito una biblioteca de selección y rango entre navegadores llamada Rangy que incorpora una versión mejorada del código que publiqué a continuación. Puede usar el módulo de guardar y restaurar la selección para esta pregunta en particular, aunque estaría tentado de usar algo como la respuesta de @Nico Burns si no está haciendo nada más con las selecciones en su proyecto y no necesita la mayor parte de un biblioteca.
Respuesta anterior
Puede usar IERange ( http://code.google.com/p/ierange/ ) para convertir TextRange de IE en algo así como un rango DOM y usarlo junto con algo como el punto de partida de la falta de párpados. Personalmente, solo usaría los algoritmos de IERange que realizan las conversiones Range <-> TextRange en lugar de usar todo. Y el objeto de selección de IE no tiene las propiedades focusNode y anchorNode, pero debería poder usar el Range / TextRange obtenido de la selección en su lugar.Podría armar algo para hacer esto, volveré a publicar aquí si lo hago.
EDITAR:
He creado una demostración de un script que hace esto. Funciona en todo lo que he probado hasta ahora, excepto por un error en Opera 9, que aún no he tenido tiempo de analizar. Los navegadores en los que funciona son IE 5.5, 6 y 7, Chrome 2, Firefox 2, 3 y 3.5 y Safari 4, todos en Windows.
http://www.timdown.co.uk/code/selections/
Tenga en cuenta que las selecciones se pueden hacer hacia atrás en los navegadores para que el nodo de enfoque esté al comienzo de la selección y al presionar la tecla de cursor derecha o izquierda moverá el cursor a una posición relativa al comienzo de la selección. No creo que sea posible replicar esto al restaurar una selección, por lo que el nodo de enfoque siempre está al final de la selección.
Escribiré esto completamente en algún momento pronto.fuente
Tuve una situación relacionada, donde específicamente necesitaba establecer la posición del cursor al FINAL de un div contenteditable. No quería usar una biblioteca completa como Rangy, y muchas soluciones eran demasiado pesadas.
Al final, se me ocurrió esta simple función jQuery para establecer la posición en quilates al final de un div contenteditable:
La teoría es simple: agregue un intervalo al final de lo editable, selecciónelo y luego elimine el intervalo, dejándonos con un cursor al final del div. Puede adaptar esta solución para insertar el tramo donde desee, colocando el cursor en un lugar específico.
El uso es simple:
¡Eso es!
fuente
<span>
, que incidentalmente romperá la pila de deshacer incorporada en el navegador. Ver stackoverflow.com/a/4238971/96100Tomé la respuesta de Nico Burns y la hice usando jQuery:
div contentEditable="true"
Necesitarás jQuery 1.6 o superior:
Mostrar fragmento de código
fuente
Después de jugar, modifiqué la respuesta anterior de párpado y lo convertí en un complemento jQuery para que pueda hacer uno de estos:
Disculpe la publicación larga de código, pero puede ayudar a alguien:
fuente
Puede aprovechar selectNodeContents, que es compatible con los navegadores modernos.
fuente
En Firefox, puede tener el texto del div en un nodo secundario (
o_div.childNodes[0]
)fuente