2010-06-20 10 views
14

J'ai écrit un peu de code dans mon gestionnaire d'événements clavier pour insérer une <br> en réponse à la pression de la touche Entrée:Faire un <br> au lieu de <div></div> en appuyant sur Entrée sur un contenteditable

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

Cette ne fonctionne que si le curseur est entre deux lettres, si c'est à la fin j'ai besoin de deux <br> -Elements. Puis-je détecter si je suis à la fin d'une ligne? Ou une autre idée de travail pour le problème d'entrée?

J'ai également essayé d'attraper l'événement-clé normal (tout en appuyant sur la touche Ctrl-enfoncée) et de créer un événement clavier avec JS où la touche Entrée est pressée avec le ctrl. Mais ce travail dosn't ...

Il n'a qu'à travailler dans Webkit/Safari ...

Répondre

23

Afin de résoudre votre problème, gardez toujours un élément br comme le dernier élément de votre contenteditable div. Cela assurera un comportement prévisible lors de l'injection d'un élément br par rapport à la valeur par défaut du navigateur d'injection d'éléments div. Vous pouvez vérifier le lastChild sur le clavier et le mouseup pour vous assurer que c'est un élément br. En supposant que vous avez un document comme:

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

Vous pouvez utiliser pour garder un élément br le code JavaScript suivant (w/jQuery 1.4+) comme le dernier élément et injecter un élément br au lieu de 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; 
     } 
     } 
    }); 

}); 

Testé sur Apple OS X avec Google Chrome 7, Mozilla Firefox 3.6, Apple Safari 5). Essayez d'utiliser ierange pour que cela fonctionne dans Windows Internet Explorer.

+4

Pas besoin de 'range.collapse (false);': vous avez déjà placé le début et la fin de la plage. Une alternative à IERange est mon propre Rangy (http://code.google.com/p/rangy), qui est similaire dans le concept, mais plus pleinement réalisé (et activement maintenu). –

0

Je lierais une fonction à l'événement keyup à supprimer et passer à
en utilisant regEx. Donc, même si cela crée un balisage étrange, il sera corrigé.

En utilisant jQuery:

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

1) .html() doit être utilisé à la place de .text() 2) cela fonctionne, mais le curseur reste avant
, pas après (après avoir appuyé sur Entrée). – Meglio