当您在contentEditable
元素上按Enter键时,每个浏览器都会以不同方式处理生成的代码: Firefox会插入BR标记,Chrome会在Internet Explorer插入P标记时插入DIV标记。
我正在拼命寻找至少在所有浏览器中使用BR或P的解决方案,最常见的答案是:
插入BR标记:
$("#editableElement").on("keypress", function(e){
if (e.which == 13) {
if (window.getSelection) {
var selection = window.getSelection(),
range = selection.getRangeAt(0),
br = document.createElement("br");
range.deleteContents();
range.insertNode(br);
range.setStartAfter(br);
range.setEndAfter(br);
selection.removeAllRanges();
selection.addRange(range);
return false;
}
}
});
但这不起作用,因为似乎浏览器不知道如何在<br>
之后设置插入符号,这意味着以下没有做任何有用的事情(特别是如果你点击当插入符号放在文本末尾时输入:)
range.setStartAfter(br);
range.setEndAfter(br);
有些人会说:使用double <br><br>
但是当您在文本节点中按Enter键时会产生两个换行符。
其他人会说总是在contentEditable的末尾添加一个<br>
,但是如果你有一个<div contenteditable><p>text here</p></div>
而你将光标放在文本的末尾然后点击回车,你就会得到错误行为。
所以我对自己说,也许我们可以使用P代替BR,而常见的答案是:
插入P标记:
document.execCommand('formatBlock', false, 'p');
但这也不能始终如一。
如您所见,所有这些解决方案都有待改进。还有其他解决方案可以解决这个问题吗?
答案 0 :(得分:10)
一种可能的解决方案:在<br>
元素后附加一个带有zero-width space字符的文本节点。这是一个非打印的零宽度字符,专门用于:
...在使用脚本时指示文本处理系统的字边界 不使用显式间距或字符之后(例如 没有可见空间但之后没有的斜线) 尽管如此,这可能是一个突破。
(维基百科)
在Chrome 48,Firefox 43和IE11中进行了测试。
$("#editableElement").on("keypress", function(e) {
//if the last character is a zero-width space, remove it
var contentEditableHTML = $("#editableElement").html();
var lastCharCode = contentEditableHTML.charCodeAt(contentEditableHTML.length - 1);
if (lastCharCode == 8203) {
$("#editableElement").html(contentEditableHTML.slice(0, -1));
}
// handle "Enter" keypress
if (e.which == 13) {
if (window.getSelection) {
var selection = window.getSelection();
var range = selection.getRangeAt(0);
var br = document.createElement("br");
var zwsp = document.createTextNode("\u200B");
var textNodeParent = document.getSelection().anchorNode.parentNode;
var inSpan = textNodeParent.nodeName == "SPAN";
var span = document.createElement("span");
// if the carat is inside a <span>, move it out of the <span> tag
if (inSpan) {
range.setStartAfter(textNodeParent);
range.setEndAfter(textNodeParent);
}
// insert the <br>
range.deleteContents();
range.insertNode(br);
range.setStartAfter(br);
range.setEndAfter(br);
// create a new span on the next line
if (inSpan) {
range.insertNode(span);
range.setStart(span, 0);
range.setEnd(span, 0);
}
// add a zero-width character
range.insertNode(zwsp);
range.setStartBefore(zwsp);
range.setEndBefore(zwsp);
// insert the new range
selection.removeAllRanges();
selection.addRange(range);
return false;
}
}
});
#editableElement {
height: 150px;
width: 500px;
border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div contenteditable=true id="editableElement">
<span>sample text</span>
</div>
答案 1 :(得分:1)
您可以看到完整的跨浏览器实施here。有很多黑客可以让它发挥作用。链接中的此代码可帮助您设置解决方案。
Geko和IE hack的例子:
doc.createElement( 'br' ).insertAfter( startBlock );
// A text node is required by Gecko only to make the cursor blink.
if ( CKEDITOR.env.gecko )
doc.createText( '' ).insertAfter( startBlock );
// IE has different behaviors regarding position.
range.setStartAt( startBlock.getNext(),
CKEDITOR.env.ie ? CKEDITOR.POSITION_BEFORE_START :
CKEDITOR.POSITION_AFTER_START );