Предотвратить добавление контента <div> при вводе - Chrome
У меня есть элемент contenteditable
, и всякий раз, когда я набираю некоторые вещи и нажимаю ENTER
, он создает новый <div>
и помещает там новый текст строки. Мне это не нравится.
Можно ли предотвратить это или, по крайней мере, просто заменить его на <br>
?
Вот демонстрация http://jsfiddle.net/jDvau/
Примечание: Это не проблема в firefox.
Ответы
Ответ 1
Попробуйте это
$('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;
}
});
Демо здесь
Ответ 2
Вы можете сделать это только с помощью CSS:
div{
background: skyblue;
padding:10px;
display: inline-block;
}
pre{
white-space: pre-wrap;
background: #EEE;
}
http://jsfiddle.net/ayiem999/HW43Q/
Ответ 3
Добавьте стиль display:inline-block;
в contenteditable
, он не будет генерировать div
, p
и span
автоматически в Chrome.
Ответ 4
Попробуйте следующее:
$('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/
Ответ 5
document.execCommand('defaultParagraphSeparator', false, 'p');
Он переопределяет поведение по умолчанию вместо абзаца.
В хроме по умолчанию поведение по умолчанию:
<div>
<br>
</div>
С помощью этой команды он будет
<p>
<br>
</p>
Теперь, когда он будет более линейным, легко иметь только <br>
, который вам понадобится.
Ответ 6
Используйте shift + enter вместо enter, чтобы поместить только один тег <br>
или обернуть текст в теги <p>
.
Ответ 7
Способ, которым contenteditable
ведет себя, когда вы нажимаете enter, зависит от браузеров, <div>
происходит на webkit (хром, сафари) и 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
Ответ 8
Я бы использовал стиль (Css), чтобы исправить проблему.
div[contenteditable=true] > div {
padding: 0;
}
Firefox действительно добавляет разрыв элемента блока
, тогда как 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/
Ответ 9
Вы можете иметь отдельные теги <p>
для каждой строки, а не использовать теги <br>
и получать большую совместимость с браузером из коробки.
Чтобы сделать это, поместите тег <p>
с некоторым текстом по умолчанию внутри содержащего контент div.
Например, вместо:
<div contenteditable></div>
Использование:
<div contenteditable>
<p>Replace this text with something awesome!</p>
</div>
jsfiddle
Протестировано в Chrome, Firefox и Edge, а второе работает одинаково в каждом.
Первое, однако, создает div в Chrome, создает разрывы строк в Firefox, а в Edge создает divs, а курсор помещается в начало текущего div вместо перехода в следующий.
Протестировано в Chrome, Firefox и Edge.
Ответ 10
добавить предупреждение по умолчанию к div
document.body.div.onkeydown = function(e) {
if ( e.keycode == 13 ){
e.preventDefault();
//add a <br>
div = document.getElementById("myDiv");
div.innerHTML += "<br>";
}
}
Ответ 11
Попробуйте использовать ckeditor. Он также обеспечивает форматирование, подобное этому в SOF.
https://github.com/galetahub/ckeditor
Ответ 12
Вы можете обернуть ваши абзацы тегом <p>
, например, он будет использовать новую строку вместо div
Пример:
<div contenteditable="true"><p>Line</p></div>
После вставки новой строки:
<div contenteditable="true"><p>Line</p><p>New Line</p></div>
Ответ 13
Сначала нам нужно захватить каждый пользователь, который вводит ключ, чтобы увидеть, нажат ли ввод, а затем мы предотвращаем создание <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();
}
}
});
Fiddle
Ответ 14
Это редактор 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/
Ответ 15
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');
.
Ответ 16
Другой способ сделать это
$('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/
Ответ 17
Предотвращение создания нового Div в содержимом editable Div на каждом клавише ввода: Решение, которое у меня есть, очень просто:
var newdiv = document.createElement("div");
newdiv.innerHTML = "Your content of div goes here";
myEditablediv.appendChild(newdiv);
Этот --- innerHTML контент предотвращает создание нового Div в содержимом editable Div для каждого ключа ввода.
Ответ 18
У меня была эта же проблема и я нашел решение (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);
});
https://jsfiddle.net/kzkxo70L/1/
Ответ 19
inserHTML
команды 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;
}
Ответ 20
Мне нравится использовать Mousetrap для работы с горячими клавишами: https://craig.is/killing/mice
Затем я просто перехватываю событие ввода, выполняя команду insertLineBreak:
Mousetrap.bindGlobal('enter', (e)=>{
window.document.execCommand('insertLineBreak', false, null);
e.preventDefault();
});
Все команды: https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand
Он работает с использованием Chrome 75 и следующего редактируемого элемента:
<pre contenteditable="true"></pre>
Также возможно использовать insertHTML:
window.document.execCommand('insertHTML', false, "\n");
Ответ 21
Можно полностью предотвратить это поведение.
См. эту скрипту
$('<div class="temp-contenteditable-el" contenteditable="true"></div>').appendTo('body').focus().remove();