2010-06-20 17 views
14

ho scritto un po 'di codice nel mio gestore di eventi tastiera per inserire un <br> in risposta alla pressione del tasto Invio:Fai un <br> invece di <div></div> premendo Invio su un contenteditable

event.preventDefault(); 
document.execCommand('InsertHTML', true, '<br>'); 

Questo funziona solo se il cursore si trova tra due lettere, se alla fine ho bisogno di due <br> -Elementi. Posso rilevare se sono alla fine di una linea? O qualche altra idea di lavoro per il problema di invio?

Ho anche provato a catturare il normale evento-chiave (senza premere il tasto ctrl premuto) e creare un evento-tastiera con JS in cui viene premuto il tasto Invio insieme al ctrl. Ma questo dosn't lavoro ...

Ha solo al lavoro in Webkit/Safari ...

risposta

23

Al fine di risolvere il problema, mantenere sempre una br elemento come ultimo elemento del div contenteditable. Ciò garantirà un comportamento prevedibile quando si inserisce un elemento br rispetto al browser predefinito per l'iniezione di elementi div. Puoi controllare lo lastChild su keyup e mouseup per assicurarti che sia un elemento di br. Supponendo di avere un documento simile:

<div id="editable" contenteditable="true"></div> 

È possibile utilizzare il seguente JavaScript (w/jQuery 1.4 +) per mantenere un elemento br come ultimo elemento e iniettare un elemento br invece di div div:

$(function(){ 

    $("#editable") 

    // make sure br is always the lastChild of contenteditable 
    .live("keyup mouseup", function(){ 
     if (!this.lastChild || this.lastChild.nodeName.toLowerCase() != "br") { 
     this.appendChild(document.createChild("br")); 
     } 
    }) 

    // use br instead of div div 
    .live("keypress", function(e){ 
     if (e.which == 13) { 
     if (window.getSelection) { 
      var selection = window.getSelection(), 
       range = selection.getRangeAt(0), 
       br = document.createElement("br"); 
      range.deleteContents(); 
      range.insertNode(br); 
      range.setStartAfter(br); 
      range.setEndAfter(br); 
      range.collapse(false); 
      selection.removeAllRanges(); 
      selection.addRange(range); 
      return false; 
     } 
     } 
    }); 

}); 

Testato su Apple OS X con Google Chrome 7, Mozilla Firefox 3.6, Apple Safari 5). Prova a utilizzare ierange per farlo funzionare in Windows Internet Explorer.

+4

Non c'è bisogno di 'range.collapse (false);': Hai già posizionato l'inizio e la fine del campo. Un'alternativa a IERange è il mio Rangy (http://code.google.com/p/rangy), che è simile nel concetto ma più pienamente realizzato (e mantenuto attivamente). –

0

Vorrei associare una funzione all'evento keyup per eliminare e passare a
utilizzando regEx. Quindi, anche se crea uno strano markup, verrà risolto.

utilizzando jQuery:

$('.myEditable').keyup(function(){ 
    var sanitazed = $(this).text().replace(/<div[^<]*?>/g, '').replace(/<\/div[^<]*?>/g, '<br>'); 
    $(this).text(sanitazed); 
}); 
+3

1) .html() deve essere usato al posto di .text() 2) funziona, ma il cursore rimane prima di
, non dopo di esso (dopo aver premuto Invio). – Meglio

Problemi correlati