Cómo hacer que la tecla de tabulación inserte un carácter de tabulación en un div de contentEditable?

Estoy construyendo un editor de texto simple al establecer contentEditable=true en un div (de todos modos, creo que textarea se comporta de la misma manera) y tengo algunos problemas con la tecla tab.

Lo que quiero es que cuando el usuario presiona la tecla de tabulación, el foco permanezca en el div y se agregue un carácter de tabulación al texto.

He resuelto la primera parte del problema al invocar preventDefault() en el objeto de evento en keydown y ahora el div no pierde el foco, pero no sé por qué no puedo insertar el personaje.

El código de entidad para la pestaña char es pero si trato de agregar esta cadena al HTMLHTML interno, reemplácelo con un espacio simple (no   solo un espacio en blanco). También probé con \t pero el resultado es el mismo.

Entonces mi pregunta es, ¿cómo puedo insertar un carácter de tabulación en el texto?

La razón por la que solo ve un espacio simple es porque las secuencias de caracteres en espacios en blanco (excepto los espacios sin interrupción) se tratan como un único carácter de espacio dentro de los divs. Si desea que el carácter de tabulación se muestre de la manera que espera, deberá colocarlo dentro de algo así como un elemento


que representa el espacio en blanco tal como está en el código fuente HTML.

Sé que esto es un poco viejo, pero esto terminó funcionando mejor para mí …

 function onKeyDown(e) { if (e.keyCode === 9) { // tab key e.preventDefault(); // this will prevent us from tabbing out of the editor // now insert four non-breaking spaces for the tab key var editor = document.getElementById("editor"); var doc = editor.ownerDocument.defaultView; var sel = doc.getSelection(); var range = sel.getRangeAt(0); var tabNode = document.createTextNode("\u00a0\u00a0\u00a0\u00a0"); range.insertNode(tabNode); range.setStartAfter(tabNode); range.setEndAfter(tabNode); sel.removeAllRanges(); sel.addRange(range); } } 

Dado que la respuesta que supuestamente era correcta no funcionó para mí, se me ocurrió esta solución que creo que funcionaría para más personas.

 $(document).on('keyup', '.editor', function(e){ //detect 'tab' key if(e.keyCode == 9){ //add tab document.execCommand('insertHTML', false, '	'); //prevent focusing on next element e.preventDefault() } }); 

Ese código funcionó para mí, pero también asegúrate de incluir el atributo de white-space:pre-wrap en tu CSS. Espero que esto haya ayudado!

las tabs y los espacios se colapsan en html en un espacio a menos que estén en una etiqueta


o que tengan white-space: pre en su estilo

puede insertar un lapso con white-space = pre y pestaña de contenido. esto se hace mejor con rangos como este:

 // adapted from http://stackoverflow.com/a/25943182/460084 function insertTab() { if (!window.getSelection) return; const sel = window.getSelection(); if (!sel.rangeCount) return; const range = sel.getRangeAt(0); range.collapse(true); const span = document.createElement('span'); span.appendChild(document.createTextNode('\t')); span.style.whiteSpace = 'pre'; range.insertNode(span); // Move the caret immediately after the inserted span range.setStartAfter(span); range.collapse(true); sel.removeAllRanges(); sel.addRange(range); } $(document).on('keydown', '.editor', function(e) { if (e.keyCode == 9) { insertTab(); e.preventDefault() } }); 
  

Yo uso esta solución:

 $('[contenteditable]').on('keydown', function(e){ if(e.keyCode == 9){ e.preventDefault(); document.execCommand('insertHTML', false, '	'); } }).css('white-space', 'pre-wrap'); 

Cuando se trabaja con código editable, un elemento


no necesita el último css agregado. keyup vs keydown y la posición de e.preventDefault () pueden diferir en los navegadores.

Nota: Creo que debe evitarse enlazar el evento clave o lo que sea de todo el documento. Tuve problemas extraños con los navegadores de escritorio Safari / iOS con elementos contentos y eventos burbujeantes.