Mam contenteditable
element i za każdym razem, gdy piszę coś i naciskam ENTER
, tworzy nowy <div>
i umieszcza tam nowy tekst. Ani trochę mi się to nie podoba.
Czy można temu zapobiec lub przynajmniej po prostu zastąpić to znakiem <br>
?
Oto demo http://jsfiddle.net/jDvau/
Uwaga: to nie jest problem w przeglądarce Firefox.
Odpowiedzi:
Spróbuj tego:
$('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/>'); // prevent the default behaviour of return key pressed return false; } });
Kliknij tutaj, aby zobaczyć demo
źródło
Możesz to zrobić za pomocą samej zmiany CSS:
div{ background: skyblue; padding:10px; display: inline-block; } pre{ white-space: pre-wrap; background: #EEE; }
http://jsfiddle.net/ayiem999/HW43Q/
źródło
Dodaj styl
display:inline-block;
docontenteditable
, nie wygenerujediv
,p
aspan
automatycznie w Chrome.źródło
*[contenteditable="true"]{display: inline-block;}
<p></p>
:(Spróbuj tego:
$('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; });
http://jsfiddle.net/rooseve/jDvau/3/
źródło
input
nie jest uruchamiany po naciśnięciu klawisza Enter. Proste rozwiązanie: dodaj coś takiego jak$(this).trigger('input')
insertHTML
Rozwiązanie robi dziwne rzeczy, kiedy nie są zagnieżdżonecontenteditable
elementy, twoje omija rozwiązanie, ale istnieje kilka problemów, dodałem go jako nowego możliwego rozwiązania.document.execCommand('defaultParagraphSeparator', false, 'p');
Zastępuje domyślne zachowanie, aby zamiast tego mieć akapit.
W Chrome domyślne zachowanie przy wejściu to:
<div> <br> </div>
Z tym poleceniem tak będzie
<p> <br> </p>
Teraz, gdy jest bardziej liniowy w poprzek, łatwo jest go mieć tylko
<br>
wtedy, gdy potrzebujesz.źródło
Użyj shift+ enterzamiast enterpo prostu wstawić pojedynczy
<br>
tag lub zawinąć tekst w<p>
tagi.źródło
Działa to we wszystkich głównych przeglądarkach (Chrome, Firefox, Safari, Edge)
document.addEventListener('keydown', event => { if (event.key === 'Enter') { document.execCommand('insertLineBreak') event.preventDefault() } })
<div class="element" contenteditable="true">Sample text</div> <p class="element" contenteditable="true">Sample text</p>
Jest jedna niedogodność. Po zakończeniu edycji elementy mogą zawierać zakończenie w
<br>
środku. Ale możesz dodać kod, aby go zmniejszyć, jeśli zajdzie taka potrzeba.Zaznacz tę odpowiedź, aby usunąć końcowe
<br>
https://stackoverflow.com/a/61237737/670839źródło
Sposób, w jaki
contenteditable
zachowuje się po naciśnięciu, enterzależy od przeglądarek, rozszerzenie<div>
dzieje się tak w przypadku Webkita (Chrome, Safari) i IE.Zmagałem się z tym kilka miesięcy temu i poprawiłem to w ten sposób:
//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); } } }); }
Mam nadzieję, że to pomoże i przepraszam za mój angielski, jeśli nie jest tak jasny, jak potrzeba.
EDYCJA : Korekta usuniętej funkcji jQuery
jQuery.browser
źródło
jQuery.browser
nie jest już częścią jQuery.navigator.userAgent.indexOf("msie") > 0
inavigator.userAgent.indexOf("webkit") > 0
if( ( e.keyCode || e.witch ) == 13 ) { ... }
musi byćif (e.keyCode === 13 || e.which === 13) { ... }
Możesz mieć osobne
<p>
tagi dla każdego wiersza, zamiast używać<br>
tagów i uzyskać większą zgodność przeglądarki po wyjęciu z pudełka.Aby to zrobić, umieść
<p>
tag z domyślnym tekstem wewnątrz edytowalnego elementu div.Na przykład zamiast:
Posługiwać się:
<div contenteditable> <p>Replace this text with something awesome!</p> </div>
jsfiddle
Testowany w Chrome, Firefox i Edge, a drugi działa tak samo w każdym.
Jednak pierwszy tworzy elementy div w Chrome, tworzy podziały wierszy w Firefoksie, aw Edge tworzy elementy div, a kursor jest umieszczany z powrotem na początku bieżącego elementu div, zamiast przesuwać się do następnego.
Przetestowano w Chrome, Firefox i Edge.
źródło
Lubię używać pułapki na myszy do obsługi skrótów klawiszowych: https://craig.is/killing/mice
Następnie po prostu przechwytuję zdarzenie enter, wykonując polecenie insertLineBreak :
Mousetrap.bindGlobal('enter', (e)=>{ window.document.execCommand('insertLineBreak', false, null); e.preventDefault(); });
Działa przy użyciu przeglądarki Chrome 75 i następującego edytowalnego elementu:
<pre contenteditable="true"></pre>
Możliwe jest również użycie insertHTML :
window.document.execCommand('insertHTML', false, "\n");
źródło
dodaj opcję zapobiegania domyślnego do elementu div
document.body.div.onkeydown = function(e) { if ( e.keycode == 13 ){ e.preventDefault(); //add a <br> div = document.getElementById("myDiv"); div.innerHTML += "<br>"; } }
źródło
document.body.div
(prawdopodobnie będziesz musiał wstawić inny kod, aby wskazać, aby poprawićdiv
jego ogólny pomysł)Użyłbym stylizacji (CSS), aby rozwiązać problem.
div[contenteditable=true] > div { padding: 0; }
Firefox rzeczywiście dodaje przerwanie elementu blokowego
, podczas gdy Chrome otacza każdą sekcję tagiem. Twój css daje elementom div wypełnienie 10 pikseli wraz z kolorem tła.
div{ background: skyblue; padding:10px; }
Alternatywnie możesz powtórzyć ten sam pożądany efekt w jQuery:
var style = $('<style>p[contenteditable=true] > div { padding: 0;}</style>'); $('html > head').append(style);
Oto widelec twoich skrzypiec http://jsfiddle.net/R4Jdz/7/
źródło
contenteditable
i używał go w innym miejscuMożesz otoczyć akapity
<p>
tagiem, na przykład pojawi się w nowej linii zamiast div Przykład:<div contenteditable="true"><p>Line</p></div>
Po wstawieniu nowego ciągu:
<div contenteditable="true"><p>Line</p><p>New Line</p></div>
źródło
Rozwiązanie
inserHTML
poleceń robi dziwne rzeczy po zagnieżdżeniucontenteditable
elementy.Wziąłem kilka pomysłów z wielu odpowiedzi tutaj i wydaje się, że na razie odpowiada to moim potrzebom:
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; }
źródło
Spróbuj użyć ckeditor. Zapewnia również formatowanie, takie jak to w SOF.
https://github.com/galetahub/ckeditor
źródło
Najpierw musimy przechwycić każdy klawisz wprowadzany przez użytkownika, aby sprawdzić, czy naciśnięto klawisz Enter, a następnie zapobiegamy
<div>
tworzeniu i tworzymy własny<br>
tag.Jest jeden problem, kiedy tworzymy go, nasz kursor pozostaje w tej samej pozycji, więc używamy Selection API, aby umieścić kursor na końcu.
Nie zapomnij dodać
<br>
tagu na końcu tekstu, ponieważ jeśli tego nie zrobisz, pierwsza enter nie utworzy nowej linii.$('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(); } } });
Skrzypce
źródło
To jest edytor HTML5 obsługiwany przez przeglądarkę. Możesz zawijać swój tekst
<p>...</p>
, a następnie za każdym razem, gdy naciśniesz ENTER, otrzymasz<p></p>
. Edytor działa również w ten sposób, że każde naciśnięcie SHIFT + ENTER wstawia<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>
Sprawdź to: http://jsfiddle.net/ZQztJ/
źródło
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>')
Gdzie
this
jest rzeczywisty kontekst, który oznaczadocument.getElementById('test');
.źródło
Inny sposób na zrobienie tego
$('button').click(function(){ $('pre').text($('div')[0].outerHTML) }); $("#content-edit").keydown(function(e) { if(e.which == 13) { $(this).find("div").prepend('<br />').contents().unwrap(); } });
http://jsfiddle.net/jDvau/11/
źródło
Zapobiegaj tworzeniu nowych elementów Div w edytowalnych treściach Div przy każdym klawiszu Enter: Rozwiązanie, które znalazłem, jest bardzo proste:
var newdiv = document.createElement("div"); newdiv.innerHTML = "Your content of div goes here"; myEditablediv.appendChild(newdiv);
Ta zawartość --- innerHTML zapobiega tworzeniu nowych elementów Div w edytowalnych treściach Div przy każdym klawiszu Enter.
źródło
W wersji roboczej edytora W3C jest kilka informacji o dodawaniu stanów do ContentEditable i zapobieganiu dodawaniu przez przeglądarkę nowego elementu po naciśnięciu klawisza Enter
plaintext-only
.<div contentEditable="plaintext-only"></div>
źródło
Można całkowicie zapobiec temu zachowaniu.
Zobacz to skrzypce
$('<div class="temp-contenteditable-el" contenteditable="true"></div>').appendTo('body').focus().remove();
źródło