Force IE contentEditable element para crear saltos de línea en la tecla Enter, sin romper Deshacer

En Internet Explorer, un contentEditable DIV crea un nuevo párrafo (

) cada vez que presiona Enter, mientras que Firefox crea una etiqueta
.

Como se discutió aquí , es posible usar JavaScript para interceptar la tecla IntroPresione y use range.pasteHTML para crear un
lugar. Pero al hacerlo se rompe el menú Deshacer; una vez que presionas Enter, ya no puedes deshacerte de ese punto.

¿Cómo puedo forzar al elemento contentEditable a crear saltos de línea individuales en Enter sin romper Deshacer?

No es una solución exacta, sino otra solución alternativa. Si usa el marcado:

 
content

Luego presionar enter creará nuevas tags div lugar de p tags.

Mantenga presionado shift cuando presione enter para los descansos, no lo mantenga presionado para los párrafos completos. Este comportamiento es el mismo por defecto en Firefox, dado un área contenteditable que contiene un párrafo: es decir,

 

If you are typing here

Presumiblemente, va a publicar el contenido editable en un servidor. Por lo tanto, no debería preocuparse realmente si tiene párrafos o tags de interrupción mientras el usuario está editando, ya que puede analizar el HTML antes del envío (o en el servidor, si lo desea) y reemplazar instancias de párrafos con interrupciones. Esto mantiene la cola UNDO en funcionamiento para el usuario, pero le permite tener su HTML tan limpio como lo desee.

Además, supongo que sabrá exactamente qué elementos DIV van a ser contentEditable. Antes de enviar el formulario, puede ejecutar cada div de contentEditable a través de una función como esta:

 function cleanContentEditableDiv(div) { var htmlString = div.innerHTML; htmlString = htmlString.replace(/<\/p>/gim,"
"); htmlString = htmlString.replace(/

/gim,""); return htmlString; }

Y usted llama esto en un bucle (que itera a través de todo el contenido EDIVs editables, usando una matriz que llamaré ceDivs), de esta manera:

 ceDivs[i].contentEditable = false; // to make sure IE doesn't try to coerce the contents again 

y entonces:

 ceDivs[i].innerHTML = cleanContentEditableDiv(ceDivs[i]); 

Una mejora en esto (especialmente si no quiere hacer esto bien en el momento del envío), podría ser limpiar el contenido de cada div en cualquier otro momento que desee (onblur, lo que sea) y asignar los contenidos de cada ceDiv a su propio elemento de forma invisible para su posterior presentación. Utilizado en combinación con su propia sugerencia CSS anterior, esto podría funcionar para usted. No conserva sus requisitos literales al pie de la letra (es decir, no obtiene Javascript para hacer que IE se comporte de manera diferente a como se ha codificado en las portadas para que se comporte), pero a todos los efectos prácticos el efecto es el mismo. Los usuarios obtienen lo que quieren y obtienes lo que quieres.

Mientras lo hace, es posible que también desee limpiar cadenas espaciales en IE. Si el usuario escribe múltiples espacios (como algunos todavía lo hacen después de los períodos), lo que IE inserta no es [espacio] [espacio] sino [espacio] & nbsp ;, un carácter de espacio inicial (String.fromCharCode (32)) más tantos como & nbsp; entidades como quedan en el espacio de ejecución.

Use
lugar de

(Probado en IE9. Tal vez nbsp; es necesario en versiones anteriores después de
(pasteHTML("
 "))
)

Úselo en el evento keydown:

 if (e.keyCode == 13) { var range = document.selection.createRange(); range.pasteHTML("
"); range.moveStart("character", 0); range.moveEnd("character", -1); range.select(); return false; }

Puede ser imposible hacer esto bien. Sin embargo, es posible hacer que las tags

vean como saltos de línea únicos, eliminando el margen integrado alrededor de las tags de párrafo, usando CSS:

 p { margin: 0; } 

Este enfoque tiene un inconveniente: si el usuario necesita copiar / pegar texto en el elemento contentEditable, el texto puede aparecer a espacio simple dentro del elemento pero a doble espacio fuera del elemento.

Peor aún, en al menos algunos casos, IE detectará automáticamente saltos de doble línea durante el pegado, reemplazándolos con tags

; esto estropeará el formateo del texto pegado.

IE vincula el nodo de texto con una etiqueta

al presionar Enter . Para lograr un salto de línea Shift + Enter . Firefox agrega una etiqueta
en la tecla Entrar . Para hacer que el comportamiento sea común en ambos navegadores, puede hacer lo siguiente:

Supongamos el siguiente marcado:

 

Javascript [supongamos que el código siguiente está en un cierre de función para que no hinche la página con globales]:

  (function () { //Initialize _shiftKeyPressed to false var _shiftKeyPressed = false; $('#editableDiv').live('keydown', function (e) { if (e.keyCode == 16) { // SHIFT key is pressed _shiftKeyPressed = true; } }).live('keyup', function (e) { if (e.keyCode == 16) { // SHIFT key is release _shiftKeyPressed = false; } }).live('keypress', function (e) { if (e.keyCode == 13 && !_shiftKeyPressed && !jQuery.browser.msie) { // Insert a PARAGRAPH in Firefox instead of a BR // Ignores SHIFT + ENTER document.execCommand("insertParagraph", false, true); } }) })(); 

Nota: esta secuencia de comandos es anterior a jQuery <1.9 para el uso del $.browser

Considere usar cuando use Internet Explorer. Es posible que no quieras hacer esto con Chrome porque el enfoque parece divertido. Es probable que desee implementar su propio código onfocus y onblur .