禁止在 ENTER-Chrome 上添加 < div >

我有一个 contenteditable元素,每当我键入一些东西并按下 ENTER,它就会创建一个新的 <div>并将新的行文本放入其中。我一点也不喜欢这样。

有没有可能防止这种情况发生,或者至少用 <br>代替它?

这里是演示 译自: 美国《 http://jsfiddle.net/jdvau/》杂志网站(http://jsfiddle.net/jDvau/)

注: 这在 Firefox 中不是一个问题。

119092 次浏览

试试这个:

$('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/

向 div 添加预防默认值

document.body.div.onkeydown = function(e) {
if ( e.keycode == 13 ){
e.preventDefault();
//add a <br>
div = document.getElementById("myDiv");
div.innerHTML += "<br>";
}
}

尝试使用 ckEditor。它也提供了像这样的格式在 SOF。

Https://github.com/galetahub/ckeditor

试试这个:

$('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;
}
});

点击这里观看演示

按下 entercontenteditable的行为方式取决于浏览器,<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

使用 shift + enter而不是 enter只是把一个单一的 <br>标签或包装您的文本在 <p>标签。

我会使用样式(CSS)来解决这个问题。

div[contenteditable=true] > div {
padding: 0;
}

Firefox 实际上添加了 block 元素 break < br/> ,而 Chrome 将每个部分包装在一个标记中。Css 为 div 提供 10px填充和背景颜色。

div{
background: skyblue;
padding:10px;
}

或者,您可以在 jQuery 中复制相同的期望效果:

var style = $('<style>p[contenteditable=true] > div { padding: 0;}</style>');
$('html > head').append(style);

这是你小提琴的叉子

首先,我们需要捕获每个键用户输入,看看如果输入被按下,然后我们阻止 <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();
}
}
});

小提琴

您可以通过一个 CSS 更改来实现这一点:

div{
background: skyblue;
padding:10px;
display: inline-block;
}


pre{
white-space: pre-wrap;
background: #EEE;
}

Http://jsfiddle.net/ayiem999/hw43q/

这是浏览器导向的 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/

另一种方法

$('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/

您可以使用 <p>标记包装您的段落,例如,它将在新行上而不是 div 上进行贴图 例如:
<div contenteditable="true"><p>Line</p></div>
插入新字符串后:
<div contenteditable="true"><p>Line</p><p>New Line</p></div>

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'); //&nbsp;
range.insertNode(nnode);
this.appendChild(bnode);
range.insertNode(nnode);
}
else
document.execCommand('insertHTML', false, '<br><br>')

其中 this是实际上下文,意味着 document.getElementById('test');

添加样式 display:inline-block;contenteditable,它不会自动生成 divpspan在 Chrome 中。

完全防止这种行为是可能的。

看这把小提琴

$('<div class="temp-contenteditable-el" contenteditable="true"></div>').appendTo('body').focus().remove();

防止在内容中创建新的 Div 可编辑的 Div 在每个输入键上: 解决方案我发现非常简单:

var newdiv = document.createElement("div");
newdiv.innerHTML = "Your content of div goes here";
myEditablediv.appendChild(newdiv);

这个—— innerHTML 内容防止在每个输入键的内容可编辑 Div 中创建 New Div。

document.execCommand('defaultParagraphSeparator', false, 'p');

它重写默认行为,改为使用段落。

在 chrome 上,输入的默认行为是:

<div>
<br>
</div>

有了这个命令,一切都会好起来的

<p>
<br>
</p>

现在,它是更多的线性横跨它很容易只有 <br>将你需要。

您可以为每一行使用单独的 <p>标记,而不是使用 <br>标记,并且可以获得更好的浏览器兼容性。

为此,在 contenteditable div 中放置一个带有默认文本的 <p>标记。

例如:

<div contenteditable></div>

用途:

<div contenteditable>
<p>Replace this text with something awesome!</p>
</div>

Jsfiddle

在 Chrome、 Firefox 和 Edge 中测试过,第二种在每种浏览器中都能正常工作。

然而,第一个在 Chrome 中创建 div,在 Firefox 中创建换行符,在 Edge 中创建 div 还有,光标被放回当前 div 的开头,而不是移动到下一个 div。

在 Chrome,Firefox 和 Edge 中测试。

当您嵌套了 contenteditable元素时,inserHTML命令解决方案会做一些奇怪的事情。

我从这里的多个答案中得到了一些想法,这似乎符合我目前的需要:

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 caret 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;
}

我喜欢用捕鼠器处理热键: https://craig.is/killing/mice

然后,我只需拦截 enter 事件,执行一个命令 插入断线:

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>

也可以使用 插入 HTML:

window.document.execCommand('insertHTML', false, "\n");

在 W3C 编辑器的草案中有一些关于将状态添加到 可编辑内容的信息,为了防止浏览器在按回车键时添加新元素,您可以使用 plaintext-only

<div contentEditable="plaintext-only"></div>

这在所有主流浏览器(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

我使用了数百个 <td>元素来输入计算值,发现 Firefox 在输入时添加了一个 <div></div><br />,这很不酷。所以我用了这个 onkeyup:

$(document).on("keyup", '.first_td_col', function(e) {
if (e.key === 'Enter' || e.keyCode === 13) {
e.preventDefault();
$(this).empty();


return false;
}
// Do calculations if not enter
});


当然,这会清除 <td>中的所有内容,甚至用户的输入。但是通过显示 No enter please.的消息,它解决了不必要的元素阻碍了计算的进行。

我们可以像这样最后清理 html


function cleanHtml(innerHTML: string) {
return innerHTML.replaceAll('<div><br></div>', '<br>')
}


可编辑这样做

const { innerHTML, innerText } = contentEl
console.log({ innerHTML, innerText, cleanHtml: cleanHtml(innerHTML) })

互联网上有很多不同的解决方案,大多数都是以同样的方式处理按键,例如 execCommandcharCodekeyCodewhich。不幸的是,这些都是过时的和非标准的功能使用 key功能,而不是这些。

也不要使用 contentEditable="plaintext-only"尝试处理 enter按键和插入 br注意到当前的选择。

检查我下面的解决方案,它在 Chrome,Firefox,Opera 和 Edge 中没有任何问题。

function handleEnterPress(e) {
if (e.key.toLowerCase() === 'enter') {
e.preventDefault();
let selection = window.getSelection();
let range = selection.getRangeAt(0);
range.insertNode(document.createElement('br'));
selection.collapseToEnd();
}
return false;
}

function handleEnterPress(e) {
if (e.key.toLowerCase() === 'enter') {
e.preventDefault();
let selection = window.getSelection();
let range = selection.getRangeAt(0);
range.insertNode(document.createElement('br'));
selection.collapseToEnd();
}
return false;
}
div[contenteditable="true"] {
background-color: bisque;
padding: 80px;
border: 1px solid black;
}
<div contenteditable="true" onkeypress="handleEnterPress(event)">Lorem ipsum dolor sit amet, consectetur adipisicing elit.</div>