Come rendere il tasto TAB Inserire un carattere di tabulazione in un div contentEditable?
-
19-09-2019 - |
Domanda
Sto costruendo un semplice editor di testo impostando contentEditable=true
su un div (in ogni caso penso che textarea si comporta nello stesso modo) e ho alcuni problemi con il tasto Tab.
Quello che voglio è che quando l'utente preme il tasto Tab, il focus rimane sulla div e un carattere di tabulazione viene aggiunto al testo.
Ho risolto la prima parte del problema chiamando preventDefault()
sull'oggetto evento su keydown e ora il div non perdere la messa a fuoco, ma non so il motivo per cui non riesco a inserire il carattere.
Il codice di entità per la scheda char è 	
ma se provo ad aggiungere questa stringa alla innerHTML Firefox sostituirlo con uno spazio semplice (non
solo uno spazio bianco). Ho provato anche con \t
ma il risultato è lo stesso.
Quindi la mia domanda è: come posso inserire un carattere di tabulazione nel testo?
Soluzione
Il motivo per cui si vede solo un semplice spazio è perché sequenze di caratteri di spaziatura (ad eccezione di spazi non-breaking) sono trattati come un singolo carattere spazio all'interno div. Se si desidera che il carattere di tabulazione per visualizzare nel modo che ci si aspetta sarà necessario metterlo dentro qualcosa come un elemento <pre>
che rende gli spazi bianchi, come è nel sorgente HTML, o all'interno di un elemento con white-space: pre
impostare tramite CSS.
Altri suggerimenti
So che questo è un po 'vecchio, ma questo finito per lavorare il meglio per me ...
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);
}
}
Dato che la risposta che era presumibilmente corretta non ha funzionato per me, mi si avvicinò con questa soluzione penso che avrebbe funzionato per più persone.
$(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()
}
});
Questo codice ha funzionato per me, ma anche fare in modo di includere l'attributo white-space:pre-wrap
nel CSS. Spero che questo ha aiutato!
schede e gli spazi sono crollati in html a uno spazio a meno che in un tag <pre>
o è white-space: pre
nel suo stile
è possibile inserire un arco con il bianco-spazio = pre e scheda contenuto. Questo è meglio fatto con gamme come questo:
// 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()
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div contenteditable=true style="border: solid" class='editor'></div>
Io uso questa soluzione:
$('[contenteditable]').on('keydown', function(e){
if(e.keyCode == 9){
e.preventDefault();
document.execCommand('insertHTML', false, '	');
}
}).css('white-space', 'pre-wrap');
Quando si lavora con il codice modificabile, un elemento <pre>
non ha bisogno l'ultima css aggiunto. keyup
vs keydown
e la posizione di di e.preventDefault () può differire nei browser.
Nota: Credo che la chiave di legame-evento o qualsiasi altra cosa da tutto il documento è da evitare. Ho avuto problemi strani con i browser desktop Safari / iOS con elementi contentEditable ed eventi bubbling.