2010-10-31 16 views
16

Mi tarea es establecer un cursor de texto deben aparecer dentro de un nodo lapso de vacío dentro de un div contentEditable.Ajuste de la posición de intercalación a un nodo vacío dentro de un elemento contentEditable

El siguiente no me causa problemas en Firefox 3.6:

<!DOCTYPE html> 
<html> 
    <head> 
     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 
     <script type="text/javascript" src="js/jquery-1.4.3.min.js"> 
     </script> 
     <style> 
      #multiple { 
       border: 1px solid #ccc; 
       width: 800px; 
       min-height: 20px; 
       padding: 5px; 
       outline: none; 
      } 
     </style> 
     <script> 
      $(document).ready(function(){ 

    var contentEditable = document.getElementById('multiple'); 
    var lastItem = contentEditable.getElementsByTagName('span').item(2); 

       var selectElementText = function(el, win){ 
        win = win || window; 
        var doc = win.document, sel, range; 
        if (win.getSelection && doc.createRange) {      
         range = doc.createRange(); 
         range.selectNodeContents(el); 
         range.collapse(false); 
         sel = win.getSelection(); 
         sel.removeAllRanges(); 
         sel.addRange(range); 
        } 
        else 
         if (doc.body.createTextRange) { 
          range = doc.body.createTextRange(); 
          range.moveToElementText(el); 
          range.select(); 
         } 
       } 

       contentEditable.focus(); 
       selectElementText(lastItem); 
      }); 
     </script> 
     <title>Range Selection Tasks (Make Me Want to Cry)</title> 
    </head> 
    <body> 
     <div id="multiple" contentEditable="true"> 
      <span style="color:red">First</span><span style="color:green">Second</span><span style="color:blue"></span> 
     </div> 
    </body> 
</html> 

... pero en Webkit y el IE, el foco se establece en la penúltima lapso. No tengo idea por qué. Funciona si pongo un espacio dentro del último tramo, pero luego obtengo una selección de rango de un carácter.

Una vez dicho esto, es aceptable tener un espacio en blanco en el último nodo si el cursor está en el principio.

Cualquier ayuda con esto sería muy apreciada. Gracias de antemano.

Respuesta

4

modelo de selección/intervalo de IE se basa en índices en el contenido del texto, sin tener en cuenta los límites del elemento. Creo que puede ser imposible establecer el foco de entrada dentro de un elemento en línea sin texto. Ciertamente, con su ejemplo no puedo establecer el foco dentro del último elemento haciendo clic en las teclas de flecha.

Funciona casi si configura cada tramo en display: block, aunque todavía existe un comportamiento muy extraño, dependiendo de la existencia de espacios en blanco en el elemento primario. Si hackas la pantalla para mirar en línea con trucos como float, inline-block y absolute position, IE tratará cada elemento como un cuadro de edición separado. Los elementos de bloque posicionados en posición relativa al lado del otro funcionan, pero eso probablemente no sea práctico.

Si te hace sentir mejor, IE9 finalmente corrige este desagradable y adopta el modelo de gama estándar. (¡Hurra!)

es aceptable tener espacios en blanco en el último nodo si el símbolo de intercalación está en el inicio.

Probablemente lo haga, a menos que un experto en selección de IE pueda pensar en algo mejor. (Llamando a Tim Down!)

+0

Gracias por su rápida y considerada respuesta. No vas a creer cuántos pirateos y soluciones diferentes he intentado al intentar que esto funcione. En realidad, si tiene experiencia con IE, probablemente tenga una idea justa. Es bueno saber que IE9 finalmente adopta el modelo estándar. Con un poco de suerte, debería tener todos mis usuarios migrados en 2019 ... – Mike

+5

¡Hola! Estoy bastante seguro de que es imposible colocar el cursor dentro de un elemento en línea vacío en IE. De manera más general, en IE es imposible ubicar el símbolo de intercalación al comienzo del primer nodo de texto dentro de un elemento. Esto también es cierto en WebKit: https://bugs.webkit.org/show_bug.cgi?id=15256#c4. Agregar espacios en blanco es tan bueno como parece, creo. He recurrido a insertar un carácter de lista de materiales Unicode ('U + FEFF', representa el ancho cero en todos los navegadores principales) al comienzo de un nodo de texto, que funciona pero deja la pesadilla logística de eliminar las listas de materiales cuando el cursor se mueve a otra parte . –

+0

¡Uf! ¡Que desagradable! Gracias. – bobince

1

Encontré una solución para Webkit, no sé si alguien encontró esto antes pero en vez de agregar programáticamente un espacio de ancho cero, puede hacer lo mismo con la propiedad de contenido css3 en el después de pseudo-selector de los elementos que desea poner el acento circunflejo. Esto tiene la ventaja de que los caracteres adicionales no aparecen en el DOM y el usuario no pueden navegar por el símbolo de intercalación entre ella. Entonces, básicamente, no necesita limpieza.

Para que esto funcione para cualquier elemento secundario de su contenido editable elemento sería algo como esto:

#mycontenteditableelement *:after { 
    content: '\200B'; 
} 

no el registro por completo, pero sospecho que esto es una solución completa.

+1

Usar bajo su propio riesgo: alguien de webkit recomendó no usar esta técnica porque el uso posterior de selector de psuedo es mal soportado en áreas contentas y puede hacer que el webkit se cuelgue o que llegue a un estado inconsistente. Nuevamente, vea webkit bugzilla: bugs.webkit.org/show_bug.cgi?id=15256 – bwindels

0

La aplicación de una altura mínima y el ancho mínimo de elementos en el interior contenteditable con inline-block puede hacer algunos buenos efectos secundarios, aunque el impacto se forma inadvertida:

#multiple * { 
    min-height: 1em; 
} 
span, b, strong, i, em, a, etc { 
    display: inline-block; 
    min-width: 1em; 
    background-color: hsla(0, 50%, 50%, .5); /* this is only a visual aid; discard @ will */ 
    vertical-align: middle; /* so elements w/ inline-block align w/ text correctly */ 
} 

Encontrará todavía hay problemas, pero si estás dispuesto a sacrificar algunos problemas por un conjunto más pequeño de otros, esto puede ser algo bueno.

11

Conjunto del elemento innerHTML a un personaje de anchura cero:

('element').innerHTML = '&#200B'; 

Ahora la carret puede ir allí.

+2

Esto funcionó muy bien; Sin embargo, utilicé '​' en mi marcado ('ÈB;' no se procesó correctamente). – duma

+4

Esta respuesta mezcla el html y el identificador de Unicode. Use "​" o "B" para referirse a un espacio sin interrupción de longitud cero. – daw

0

Para mí configurarlo contenido de contenteditable div a <br> funciona. Intenté configurarlo en nbsp;, pero eso crea espacio de caracteres adicionales en el div antes de comenzar a editar.

Espero que esto ayude.

Cuestiones relacionadas