Tengo un área
contengan texto. La idea es que estos elementos de tramo representarán texto con estilo que no se puede editar, pero se pueden eliminar desde el área
pulsando la tecla de retroceso.
La colocación del cursor es el gran problema aquí. si elimina uno de estos elementos , el cursor salta al final de
He preparado un violín que demostrará esto. Necesito que esto funcione solo en Chrome , y otros navegadores no son de preocupación por ahora o tienen soluciones alternativas. (También tenga en cuenta que el Fiddle preparado está diseñado para demostrar esto solo en Chrome).
Violín
Instrucción Fiddle: versión de Chrome 39.0.2171.95 m (64 bits) reproducida también en 32 bits
- Escriba “123”
- Retroceso “3” Retroceso “2” Retroceso “1”

Detalles relacionados
Investigando esto extensamente, me he encontrado con varias preguntas de SO que son similares, pero tomar prestadas las soluciones asociadas no ha resultado ser la bala de plata que busco. También he encontrado problemas para el proyecto Chrome que parecen apuntar (tal vez no de la manera exacta) al problema descrito anteriormente, y se pueden ver a continuación.
- Problema 384357: posición de Caret dentro de la región contenteditable con nodos no editables
- Problema 385003: El estilo de inserción de intercalación es incorrecto al llegar al final de una línea en un elemento contenteditable
- Problema 71598: Caret en posición incorrecta después del elemento no editable al final del contenido Editable
La solución SO más cercana que he encontrado puede estar aquí . La idea en esta solución es colocar
caracteres después de los elementos
, pero si ahora quiero eliminar mi
, en su lugar,
el
… forzando al cursor a saltar al final, ofreciendo una experiencia de IU extraña al no eliminar mi
en mi “pulsación de tecla de eliminación inicial”.
Pregunta
¿Alguien ha experimentado este problema y ha encontrado un trabajo alternativo? Doy la bienvenida a cualquier posible solución, incluso cuando JS hacky como vengan. He aprendido que el apalancamiento de contenteditable
viene con una larga lista de problemas, pero esta parece ser la última dificultad que tengo actualmente .
- Desactiva la corrección gtwigtical en un div satisfactorio en Firefox
- Cómo hacer anclaje clicable en contentEditable div?
- Obtener la posición de interés en Div entretenido, incluidas las tags
- Modificar texto en una div contenida sin restablecer la posición de cursor (cursor)
- Permitir el movimiento solo de dentro de contentEditable
No sé por qué sucede esto, pero tuve la sensación de que tiene algo que ver con el tamaño del
, así que traté de jugar con la propiedad de display
. Después de configurarlo inline-block
en inline-block
y de jugar un poco con el texto, descubrí que el problema desapareció después de realizar algunas ediciones, específicamente agregando una nueva línea.
Vi que, por alguna razón, la etiqueta
se mantiene en div.main
después de eliminar mi nueva línea, pero la apariencia del
y la forma en que responde a las teclas de flecha es la misma que si hubiera no hay una nueva línea en él.
¡Así que reinicié el violín con el cambio de CSS y una etiqueta
en div.main
y viola!
Entonces para concluir:
- Agregar
display: inline-block
to div.main
- agrega un
al final de div.main
JSFiddle Link
El problema es que su elemento contenteditable
es un div
, que por defecto es display: block
. Esto es lo que causa su problema de posición de cuidado. Esto se puede solucionar haciendo que el div
más externo no sea editable y agregando un nuevo div
editable que se tratará como inline-block
.
El nuevo HTML tendría un nuevo div
justo dentro del externo (y la etiqueta de cierre correspondiente al final):
...
Y agrega esto a tu CSS:
div#editable { display: inline-block; }
Con el fin de ver mejor la intercalación cuando se trata de elementos de span
, también he agregado margin: 2px
a la regla para div.main span
en CSS, pero esto no es necesario para evitar el problema de salto de intercalación informado en la pregunta.
Aquí hay un violín .
A medida que comenzó a descubrir, contenteditable
se maneja de forma incoherente en todos los navegadores. Hace unos años, comencé a trabajar en un proyecto (editor XML en el navegador) donde pensé que contenteditable
haría todo más fácil. Luego, cuando desarrollé la aplicación, pronto me di cuenta de que estaba asumiendo las funciones que creía que lo que me daría la contenteditable
me daría gratis. Hoy, lo único que me permite contenteditable
es que enciende los eventos del teclado en los elementos que quiero editar. Todo lo demás, incluido el movimiento del cursor y la visualización del cursor, se gestiona mediante un código personalizado.
Por lo tanto, tengo una implementación ligeramente más clara de su enfoque, que se basa en el evento de input
que se desencadena cuando se actualiza un campo contenteditable
. Este evento no es compatible con IE, pero parece que contenteditable
es bastante inseguro en IE de todos modos.
Básicamente inyecta elementos alrededor de cada elemento marcado como contenteditable="false"
. Probablemente podría hacerse en la carga inicial en lugar de solo en el evento de input
, pero pensé que podría haber formas de inyectar más span
a la región, por lo que la input
debería dar cuenta de esto.
Las limitaciones incluyen un comportamiento extraño que rodea las teclas de flecha, como te has visto a ti mismo. Sobre todo lo que he visto es que el cursor mantiene su posición correcta cuando retrocedes por los tramos, pero no cuando avanzas.
JSFiddle Link
Javascript
$('#main').on('input', function() { var first = true; $(this).contents().each(function(){ if ($(this).is('[contenteditable=false]')) { $("").insertAfter(this); if (first) { $("").insertBefore(this); first = false } } }); }).trigger('input');
CSS
div.main { width: 400px; height: 250px; border: solid 1px black; } div.main span { width:40px; background-color: red; border-radius: 5px; color: white; cursor: pointer; } i.wrapper { font-style: normal; }
He encontrado una manera estrafalaria de resolver el problema inicial del comportamiento incorrecto del cursor al final del
con algo de JQuery. Básicamente, estoy insertando un
vacío para que el cursor “cierre” al final del contenido de
. Esta etiqueta funciona para mí porque no hay diferencia de UI para el usuario final al retroceder desde el texto normal debido a la anulación font-style: normal
(ver violín), y también necesitaba algo diferente a
para insertar
No estoy particularmente entusiasmado con esta solución, especialmente al elegir un
solo porque, pero no he encontrado una mejor alternativa, y aún así recibo mejores soluciones, ¡si es que existen! Planeo seguir trabajando en esto para poder descubrir las teclas de flecha también, pero afortunadamente solo me molesta este problema en el Fiddle y no mi código.
Fiddle (solo Chrome)
item item item
function hackCursor() { return $('#main :last-child').get(0).tagName === 'SPAN' ? $('#main span:last-child').after('') : false; } $(function(){ hackCursor(); $('#main').bind({ 'keyup': function(e) { hackCursor(); } }) });
Simplemente agregue una nueva línea char ( \n
) antes de cerrar la etiqueta contenteditable
. Por ejemplo, en JavaScript: var html = '
' + content + "\n" + '
'
- ¿De qué sirve en html?
- Evita agregar editable en ENTER – Chrome
- Imitar una entrada de tipo contraseña mientras usa un div contennteitable
- ContentEditable se enfoca en Chrome / Safari
- ¿Hay alguna manera de evitar que un elemento contentEditable se desplace cuando el cursor llega al final?
- ¿Es posible usar contentEditable con jQuery DatePicker?
- Detecta el evento de keyup del hijo conteniditable cuyo padre es un div contenteditable
- Información confiable de navegador cruzado en ContentEditable
- Cómo hacer que el contenido de un elemento se pueda editar con JavaScript (o jQuery)
- reemplace innerHTML en contenteditable div
- Editores de texto editables de contenido