我有一个contenteditable
元素,每当我输入一些内容并点击ENTER
它时,都会创建一个新元素并将<div>
新的行文本放置在其中。我一点都不喜欢。
是否可以防止这种情况发生,或者至少将其替换为<br>
?
这是演示http://jsfiddle.net/jDvau/
注意:这不是在Firefox中的问题。
我有一个contenteditable
元素,每当我输入一些内容并点击ENTER
它时,都会创建一个新元素并将<div>
新的行文本放置在其中。我一点都不喜欢。
是否可以防止这种情况发生,或者至少将其替换为<br>
?
这是演示http://jsfiddle.net/jDvau/
注意:这不是在Firefox中的问题。
Answers:
试试这个:
$('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;
}
});
您可以通过更改CSS来做到这一点:
div{
background: skyblue;
padding:10px;
display: inline-block;
}
pre{
white-space: pre-wrap;
background: #EEE;
}
试试这个:
$('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;
});
input
在您按Enter键时不会触发。一个简单的解决方案:添加类似$(this).trigger('input')
insertHTML
当存在嵌套contenteditable
元素时,该解决方案会做一些奇怪的事情,您的解决方案会规避但还有更多问题,我将其添加为新的可能解决方案。
document.execCommand('defaultParagraphSeparator', false, 'p');
它覆盖默认行为以改为具有段落。
在chrome上,enter的默认行为是:
<div>
<br>
</div>
有了这个命令,它将成为
<p>
<br>
</p>
现在,它在整个过程中更加线性,只<br>
需要您就可以轻松拥有它。
使用shift+ enter而不是enter仅将单个<br>
标签放入或将文本包装在<p>
标签中。
contenteditable
按下时的行为方式enter取决于浏览器,<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);
}
}
});
}
希望对您有所帮助,如果英语不够清晰,请对我的英语感到抱歉。
编辑:删除的jQuery函数的更正jQuery.browser
jQuery.browser
它不再是jQuery的一部分。
navigator.userAgent.indexOf("msie") > 0
和navigator.userAgent.indexOf("webkit") > 0
if( ( e.keyCode || e.witch ) == 13 ) { ... }
需要成为if (e.keyCode === 13 || e.which === 13) { ... }
我喜欢使用捕鼠器来处理热键:https://craig.is/killing/mice
然后,我只是截取enter事件,执行命令insertLineBreak:
Mousetrap.bindGlobal('enter', (e)=>{
window.document.execCommand('insertLineBreak', false, null);
e.preventDefault();
});
所有命令:https : //developer.mozilla.org/zh-CN/docs/Web/API/Document/execCommand
它可以使用Chrome 75和以下可编辑元素工作:
<pre contenteditable="true"></pre>
也可以使用insertHTML:
window.document.execCommand('insertHTML', false, "\n");
向div添加一个阻止默认值
document.body.div.onkeydown = function(e) {
if ( e.keycode == 13 ){
e.preventDefault();
//add a <br>
div = document.getElementById("myDiv");
div.innerHTML += "<br>";
}
}
document.body.div
(您可能需要输入一些其他代码来纠正div
它的一般想法)
我会使用样式(Css)来解决此问题。
div[contenteditable=true] > div {
padding: 0;
}
Firefox确实添加了一个block元素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/
contenteditable
并将其在其他地方使用
您可以<p>
为每行使用单独的标签,而不是使用<br>
标签,从而可以提高浏览器的兼容性。
为此,请将<p>
带有一些默认文本的标签放在contenteditable div内。
例如,代替:
<div contenteditable></div>
用:
<div contenteditable>
<p>Replace this text with something awesome!</p>
</div>
在Chrome,Firefox和Edge上进行了测试,第二个在每个版本中均相同。
但是,第一个在Chrome中创建div,在Firefox中创建换行符,在Edge中创建div 和将光标放回到当前div的开头,而不是移至下一个div。
在Chrome,Firefox和Edge中进行了测试。
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;
}
尝试使用ckeditor。它还在SOF中提供了这种格式。
首先,我们需要捕获每个关键用户的回车键,以查看是否按下了回车键,然后阻止<div>
创建,并创建自己的<br>
标签。
有一个问题,当我们创建它时,光标停留在相同的位置,因此我们使用Selection 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/
这适用于所有主要浏览器(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>
有一个不便之处。完成编辑后,元素可能<br>
在内部包含结尾。但是,如果需要,您可以添加代码以将其缩减。
检查此答案以删除结尾的<br>
https://stackoverflow.com/a/61237737/670839
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();
}
});
防止在每个Enter键的内容可编辑Div中创建新Div:解决方案我发现非常简单:
var newdiv = document.createElement("div");
newdiv.innerHTML = "Your content of div goes here";
myEditablediv.appendChild(newdiv);
该--- innerHTML内容可防止在每个Enter键上的内容可编辑Div中创建新Div。
在W3C编辑器的草案中,有一些有关将状态添加到ContentEditable中的信息,并且可以防止使用浏览器在按Enter时添加新元素plaintext-only
。
<div contentEditable="plaintext-only"></div>