Запретить contenteditable добавление на ENTER-Chrome
у меня есть contenteditable элемент, и всякий раз, когда я набираю некоторые вещи и нажмите ENTER он создает новый <div> и помещает туда новый текст строки. Мне это совсем не нравится.
можно ли предотвратить или хотя бы просто заменить <br>?
вот демо http://jsfiddle.net/jDvau/
Примечание: это не проблема в Firefox.
20 ответов:
попробуй такое
$('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; } });
вы можете сделать это с помощью всего лишь изменения в CSS:
div{ background: skyblue; padding:10px; display: inline-block; } pre{ white-space: pre-wrap; background: #EEE; }
добавить стиль
display:inline-block;доcontenteditable, это не будет генерироватьdiv,pиspanавтоматически в Chrome.
попробуйте это:
$('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; });
использовать shift+введите вместо введите просто поставить один
<br>тег в или обернуть текст в<p>теги.
document.execCommand('defaultParagraphSeparator', false, 'p');Он переопределяет поведение по умолчанию для пункта.
в chrome поведение по умолчанию при вводе:
<div> <br> </div>С этой командой это будет
<p> <br> </p>теперь, когда он более линейный, легко иметь только
<br>будет нужно.
вот так
contenteditableведет себя при нажатии введите зависит от браузеров,<div>происходит на webkit (chrome, safari) и IE.я боролся с этим несколько месяцев назад и я исправил это так :
//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); } } }); }Я надеюсь, что это поможет, и извините за мой английский, если это не ясно, как это необходимо.
EDIT: исправление удаленной функции jQuery
jQuery.browser
Я бы использовал стиль (Css), чтобы исправить эту проблему.
div[contenteditable=true] > div { padding: 0; }Firefox действительно добавляет блок элемент break
, в то время как Chrome обертывает каждый раздел в тег. Вы css дает divs заполнение 10px вместе с цветом фона.div{ background: skyblue; padding:10px; }кроме того, вы можете повторить тот же желаемый эффект в jQuery:
var style = $('<style>p[contenteditable=true] > div { padding: 0;}</style>'); $('html > head').append(style);вот вилка вашей скрипки http://jsfiddle.net/R4Jdz/7/
вы можете обернуть свои абзацы с
<p>тег, например, он будет появляться на новой строке вместо div Пример:<div contenteditable="true"><p>Line</p></div>
После вставки новой строки:<div contenteditable="true"><p>Line</p><p>New Line</p></div>
вы можете иметь отдельные
<p>теги для каждой строки, а не с помощью<br>теги и получить большую совместимость с браузерами "из коробки".для этого поставьте
<p>тег с некоторым текстом по умолчанию внутри contenteditable div.например, вместо:
<div contenteditable></div>использование:
<div contenteditable> <p>Replace this text with something awesome!</p> </div>протестировано в Chrome, Firefox и Edge, а второй работает одинаково в каждом.
в сначала, однако, создает divs в Chrome, создает разрывы строк в Firefox, а в Edge создает divs и курсор помещается обратно в начало текущего div вместо перехода в следующий.
протестировано в Chrome, Firefox и Edge.
добавить предотвращение по умолчанию для div
document.body.div.onkeydown = function(e) { if ( e.keycode == 13 ){ e.preventDefault(); //add a <br> div = document.getElementById("myDiv"); div.innerHTML += "<br>"; } }
Сначала нам нужно захватить каждый ключ пользователя enter, чтобы увидеть, если enter нажата, то мы предотвращаем
<div>создание и мы создаем нашу собственную<br>тег.есть одна проблема, когда мы создаем его, наш курсор остается в том же положении, поэтому мы используем API выбора чтобы поместить наш курсор в конце.
не забудьте добавить
<br>тег в конце текста, потому что если вы не первый ввод не будет делать новую строку.$('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(); } } });
это браузер, направленный редактор HTML5. Вы можете обернуть свой текст с
<p>...</p>, то всякий раз, когда вы нажимаете ENTER вы получаете<p></p>. Кроме того, редактор работает таким образом, что всякий раз, когда вы нажимаете SHIFT+ENTER, он вставляет<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>проверить это: http://jsfiddle.net/ZQztJ/
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>')здесь
thisэто фактический контекст, который означаетdocument.getElementById('test');.
другой способ сделать это
$('button').click(function(){ $('pre').text($('div')[0].outerHTML) }); $("#content-edit").keydown(function(e) { if(e.which == 13) { $(this).find("div").prepend('<br />').contents().unwrap(); } });
У меня была такая же проблема, и я нашел решение (CHROME, MSIE, FIREFOX), следуйте моему коду по ссылке.
$(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); });
запретить создание нового Div в контенте редактируемый Div на каждом ключе ввода: решение, которое я нашел, очень просто:
var newdiv = document.createElement("div"); newdiv.innerHTML = "Your content of div goes here"; myEditablediv.appendChild(newdiv);это - - - содержимое innerHTML предотвращает создание нового Div в редактируемом Div содержимом на каждом ключе ввода.
The
inserHTMLкомандное решение делает некоторые странные вещи, когда вы вложилиcontenteditableэлементы.Я взял некоторые идеи из нескольких ответов здесь, и это, кажется, соответствует моим потребностям на данный момент:
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; }
можно полностью предотвратить такое поведение.
$('<div class="temp-contenteditable-el" contenteditable="true"></div>').appendTo('body').focus().remove();
Comments