J'ai un élément contenteditable
et chaque fois que je tape des éléments et que je clique sur ENTER
, un nouveau <div>
est créé et le texte de la nouvelle ligne y est placé. Je n'aime pas ça un petit peu.
Est-il possible d'empêcher cela ou du moins de le remplacer par un <br>
?
Voici la démo http://jsfiddle.net/jDvau/
Remarque: Ce n'est pas un problème dans Firefox.
Essaye ça
$('div[contenteditable]').keydown(function(e) {
// trap the return key being pressed
if (e.keyCode === 13) {
// insert 2 br tags (if only one br tag is inserted the cursor won't go to the next line)
document.execCommand('insertHTML', false, '<br><br>');
// prevent the default behaviour of return key pressed
return false;
}
});
Vous pouvez le faire avec juste un changement CSS:
div{
background: skyblue;
padding:10px;
display: inline-block;
}
pre{
white-space: pre-wrap;
background: #EEE;
}
Ajoutez le style display:inline-block;
à contenteditable
. Il ne générera pas div
, p
et span
automatiquement dans Chrome.
Essaye ça:
$('div[contenteditable="true"]').keypress(function(event) {
if (event.which != 13)
return true;
var docFragment = document.createDocumentFragment();
//add a new line
var newEle = document.createTextNode('\n');
docFragment.appendChild(newEle);
//add the br, or p, or something else
newEle = document.createElement('br');
docFragment.appendChild(newEle);
//make the br replace selection
var range = window.getSelection().getRangeAt(0);
range.deleteContents();
range.insertNode(docFragment);
//create a new range
range = document.createRange();
range.setStartAfter(newEle);
range.collapse(true);
//make the cursor there
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
return false;
});
Utilisation shift+enter au lieu de enter insérer une seule balise <br>
ou envelopper votre texte dans des balises <p>
.
document.execCommand('defaultParagraphSeparator', false, 'p');
Il remplace le comportement par défaut pour avoir un paragraphe à la place.
Sur chrome, le comportement par défaut à entrer est:
<div>
<br>
</div>
Avec cette commande ça va être
<p>
<br>
</p>
Maintenant que c'est plus linéaire, il est facile de n'avoir que <br>
dont vous auriez besoin.
La manière dont contenteditable
se comporte lorsque vous appuyez sur enter dépend des navigateurs, le <div>
arrive sur le Webkit (chrome, safari) et IE.
J'ai eu du mal avec cela il y a quelques mois et je l'ai corrigé de cette façon:
//I recommand you trigger this in case of focus on your contenteditable
if( navigator.userAgent.indexOf("msie") > 0 || navigator.userAgent.indexOf("webkit") > 0 ) {
//Add <br> to the end of the field for chrome and safari to allow further insertion
if(navigator.userAgent.indexOf("webkit") > 0)
{
if ( !this.lastChild || this.lastChild.nodeName.toLowerCase() != "br" ) {
$(this).html( $(this).html()+'<br />' );
}
}
$(this).keypress( function(e) {
if( ( e.keyCode || e.witch ) == 13 ) {
e.preventDefault();
if( navigator.userAgent.indexOf("msie") > 0 ) {
insertHtml('<br />');
}
else {
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);
}
}
});
}
J'espère que cela vous aidera et désolé pour mon anglais si ce n'est pas aussi clair que nécessaire.
EDIT: Correction de la fonction jQuery supprimée jQuery.browser
J'utiliserais un style (Css) pour résoudre le problème.
div[contenteditable=true] > div {
padding: 0;
}
Firefox ajoute en effet une rupture d'élément de bloc
, alors que Chrome enveloppe chaque section dans une balise. Vous css donne à div un remplissage de 10px avec la couleur de fond.
div{
background: skyblue;
padding:10px;
}
Vous pouvez également répliquer le même effet souhaité dans jQuery:
var style = $('<style>p[contenteditable=true] > div { padding: 0;}</style>');
$('html > head').append(style);
Voici une fourchette de votre violon http://jsfiddle.net/R4Jdz/7/
Vous pouvez avoir des balises <p>
séparées pour chaque ligne plutôt que d'utiliser des balises <br>
et obtenir une meilleure compatibilité avec les navigateurs.
Pour ce faire, insérez une balise <p>
avec du texte par défaut à l'intérieur du div contenteditable.
Par exemple, au lieu de:
<div contenteditable></div>
Utilisation:
<div contenteditable>
<p>Replace this text with something awesome!</p>
</div>
Testé dans Chrome, Firefox et Edge, et le second fonctionne de la même manière dans chacun.
Le premier, cependant, crée des div dans Chrome, des sauts de ligne dans Firefox et, dans Edge, crée des divs et le curseur est replacé au début du div actuel au lieu de passer au suivant.
Testé sous Chrome, Firefox et Edge.
Essayez d'utiliser ckeditor. Il fournit également un formatage semblable à celui-ci dans les fichiers SOF.
Vous pouvez envelopper vos paragraphes avec la balise <p>
, par exemple, il apparaîtrait sur une nouvelle ligne au lieu de div .__<div contenteditable="true"><p>Line</p></div>
Après avoir inséré une nouvelle chaîne:<div contenteditable="true"><p>Line</p><p>New Line</p></div>
Nous devons d’abord capturer chaque entrée d’utilisateur clé pour voir si elle est enfoncée, puis nous empêchons la création de <div>
et nous créons notre propre balise <br>
.
Il y a un problème, lorsque nous le créons, notre curseur reste à la même position et nous utilisons API de sélection pour placer notre curseur à la fin.
N'oubliez pas d'ajouter une balise <br>
à la fin de votre texte car sinon, la première entrée ne créera pas de nouvelle ligne.
$('div[contenteditable]').on('keydown', function(e) {
var key = e.keyCode,
el = $(this)[0];
// If Enter
if (key === 13) {
e.preventDefault(); // Prevent the <div /> creation.
$(this).append('<br>'); // Add the <br at the end
// Place selection at the end
// http://stackoverflow.com/questions/4233265/contenteditable-set-caret-at-the-end-of-the-text-cross-browser
if (typeof window.getSelection != "undefined"
&& typeof document.createRange != "undefined") {
var range = document.createRange();
range.selectNodeContents(el);
range.collapse(false);
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
} else if (typeof document.body.createTextRange != "undefined") {
var textRange = document.body.createTextRange();
textRange.moveToElementText(el);
textRange.collapse(false);
textRange.select();
}
}
});
if (navigator.userAgent.toLowerCase().indexOf('msie') > -1) {
var range = document.getSelection();
range.pasteHTML(range.htmlText + '<br><br>');
}
else if(navigator.userAgent.toLocaleLowerCase().indexOf('trident') > -1) {
var range = document.getSelection().getRangeAt(0); //get caret
var nnode = document.createElement('br');
var bnode = document.createTextNode('\u00A0'); //
range.insertNode(nnode);
this.appendChild(bnode);
range.insertNode(nnode);
}
else
document.execCommand('insertHTML', false, '<br><br>')
Où this
est le contexte réel qui signifie document.getElementById('test');
.
ajouter un empêchement par défaut à la div
document.body.div.onkeydown = function(e) {
if ( e.keycode == 13 ){
e.preventDefault();
//add a <br>
div = document.getElementById("myDiv");
div.innerHTML += "<br>";
}
}
C'est l'éditeur HTML5 dirigé par le navigateur. Vous pouvez envelopper votre texte avec <p>...</p>
. Chaque fois que vous appuyez sur ENTREE, vous obtenez <p></p>
. En outre, l'éditeur fonctionne de telle manière que chaque fois que vous appuyez sur SHIFT + ENTER, il insère <br />
.
<div contenteditable="true"><p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dolor veniam asperiores laudantium repudiandae doloremque sed perferendis obcaecati delectus autem perspiciatis aut excepturi et nesciunt error ad incidunt impedit quia dolores rerum animi provident dolore corporis libero sunt enim. Ad magnam omnis quidem qui voluptas ut minima similique obcaecati doloremque atque!
<br /><br />
Type some stuff, hit ENTER a few times, then press the button.
</p>
</div>
Vérifiez ceci: http://jsfiddle.net/ZQztJ/
J'ai eu ce même problème et trouvé la solution (CHROME, MSIE, FIREFOX), suivez mon code dans le lien.
$(document).on('click','#myButton',function() {
if (navigator.userAgent.toLowerCase().indexOf('chrome') > -1)
var str = $('#myDiv').html().replace(/<br>/gi,'').replace(/<div>/gi,'<br>').replace(/<\/div>/gi,'');
else if (navigator.userAgent.toLowerCase().indexOf("firefox") > -1)
var str = $('#myDiv').html().replace(/<\/br>/gi,'').replace(/<br>/gi,'<br>').replace(/<\/br>/gi,'');
else if (navigator.userAgent.toLowerCase().indexOf("msie") == -1)
var str = $('#myDiv').html().replace(/<br>/gi,'').replace(/<p>/gi,'<br>').replace(/<\/p>/gi,'');
$('#myDiv2').removeClass('invisible').addClass('visible').text(str);
$('#myDiv3').removeClass('invisible').addClass('visible').html(str);
});
Une autre façon de le faire
$('button').click(function(){
$('pre').text($('div')[0].outerHTML)
});
$("#content-edit").keydown(function(e) {
if(e.which == 13) {
$(this).find("div").prepend('<br />').contents().unwrap();
}
});
Empêcher la création d'une nouvelle div dans le contenu éditable Div sur chaque touche d'entrée: Solution que j'ai trouvée est très simple:
var newdiv = document.createElement("div");
newdiv.innerHTML = "Your content of div goes here";
myEditablediv.appendChild(newdiv);
Ce contenu --- innerHTML empêche la création d'une nouvelle div dans le contenu éditable div sur chaque touche Entrée.
La solution de commande inserHTML
fait des choses étranges lorsque vous avez imbriqué des éléments contenteditable
.
J'ai pris quelques idées de réponses multiples ici, et cela semble répondre à mes besoins pour l'instant:
element.addEventListener('keydown', function onKeyDown(e) {
// Only listen for plain returns, without any modifier keys
if (e.which != 13 || e.shiftKey || e.ctrlKey || e.altKey) {
return;
}
let doc_fragment = document.createDocumentFragment();
// Create a new break element
let new_ele = document.createElement('br');
doc_fragment.appendChild(new_ele);
// Get the current selection, and make sure the content is removed (if any)
let range = window.getSelection().getRangeAt(0);
range.deleteContents();
// See if the selection container has any next siblings
// If not: add another break, otherwise the cursor won't move
if (!hasNextSibling(range.endContainer)) {
let extra_break = document.createElement('br');
doc_fragment.appendChild(extra_break);
}
range.insertNode(doc_fragment);
//create a new range
range = document.createRange();
range.setStartAfter(new_ele);
range.collapse(true);
//make the cursor there
let sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
e.stopPropagation();
e.preventDefault();
return false;
});
// See if the given node has a next sibling.
// Either any element or a non-empty node
function hasNextSibling(node) {
if (node.nextElementSibling) {
return true;
}
while (node.nextSibling) {
node = node.nextSibling;
if (node.length > 0) {
return true;
}
}
return false;
}
J'aime utiliser Mousetrap pour les raccourcis clavier: https://craig.is/killing/mice
Ensuite, je viens d'intercepter l'événement enter en exécutant une commande insertLineBreak :
Mousetrap.bindGlobal('enter', (e)=>{
window.document.execCommand('insertLineBreak', false, null);
e.preventDefault();
});
Toutes les commandes: https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand
Cela fonctionne avec Chrome 75 et l'élément éditable suivant:
<pre contenteditable="true"></pre>
Il est également possible d'utiliser insertHTML :
window.document.execCommand('insertHTML', false, "\n");