Html 强制IE contentEditable元素在Enter键上创建换行符,而不中断撤消
在Internet Explorer上,每次按Enter键时,contentEditable DIV都会创建一个新段落(Html 强制IE contentEditable元素在Enter键上创建换行符,而不中断撤消,html,undo,contenteditable,Html,Undo,Contenteditable,在Internet Explorer上,每次按Enter键时,contentEditable DIV都会创建一个新段落(),而Firefox会创建一个标记 如前所述,可以使用JavaScript截取Enter键并使用range.pasteHTML创建。但这样做会破坏撤销菜单;一旦按Enter键,就无法撤消超过该点的操作 如何强制contentEditable元素在Enter键上创建单行换行符而不中断撤消?要正确执行此操作可能是不可能的。但是,可以通过删除段落标记周围的内置边距,使用CSS使标记看
),而Firefox会创建一个
标记
如前所述,可以使用JavaScript截取Enter键并使用range.pasteHTML创建
。但这样做会破坏撤销菜单;一旦按Enter键,就无法撤消超过该点的操作
如何强制contentEditable元素在Enter键上创建单行换行符而不中断撤消?要正确执行此操作可能是不可能的。但是,可以通过删除段落标记周围的内置边距,使用CSS使
标记看起来像单行换行符:
p { margin: 0; }
这种方法有一个缺点:如果用户需要在contentEditable元素中复制/粘贴文本,则文本可能在元素内部以单间距显示,但在元素外部以双间距显示
更糟糕的是,至少在某些情况下,IE会在粘贴过程中自动检测到双线中断,并将其替换为
标记;这会弄乱粘贴文本的格式。这不是一个确切的解决方案,而是另一种解决方法。如果使用标记:
<div contenteditable="true">
<div>
content
</div>
<div>
内容
然后按enter键将创建新的
div
标记,而不是p
标记。您可能要将可编辑内容发布回服务器。因此,在用户编辑时,您不应该真正关心是否放置了段落或打断标记,因为您可以在提交之前(或者在服务器上,如果您愿意的话)解析HTML,并用打断替换段落实例。这可以让用户保持撤消队列的运行,但可以让HTML尽可能干净
我进一步假设您将确切地知道哪些DIV元素将是可编辑的。在提交表单之前,您可以通过如下函数运行每个contentEditable div:
function cleanContentEditableDiv(div) {
var htmlString = div.innerHTML;
htmlString = htmlString.replace(/<\/p>/gim,"<br/>");
htmlString = htmlString.replace(/<p>/gim,"");
return htmlString;
}
ceDivs[i].contentEditable = false; // to make sure IE doesn't try to coerce the contents again
然后:
ceDivs[i].innerHTML = cleanContentEditableDiv(ceDivs[i]);
对此的一个改进(特别是如果您不想在提交时正确执行此操作),可能是在您喜欢的任何其他时间(onblur,无论什么)清理每个此类div的内容,并将每个ceDiv的内容分配给其自己的不可见表单元素,以便稍后提交。结合上面您自己的CSS建议使用,这可能适合您。它不会严格保留您的文字要求(即,它不会让Javascript使IE的行为与它在封面下的行为有所不同),但对于所有实际目的,效果都是一样的。用户得到他们想要的,你也得到你想要的
当你这样做的时候,你可能还想清理IE中的空格字符串。如果用户键入多个空格(有些空格在句点后仍然如此),IE插入的不是[space][space],而是[space],一个初始空格字符(String.fromCharCode(32))加上空格中剩余的实体数。按住shift键在按enter键进行分隔时,不要按住shift键进行完整段落。这种行为在Firefox中默认情况下是相同的,给定一个包含段落的contenteditable区域:即
<div contenteditable="true">
<p>If you are typing here</p>
<div>
如果你在这里打字
使用
而不是
(在IE9中测试。在
(粘贴HTML(
))之后的旧版本中可能需要nbsp;
)
在按键关闭事件中使用它:
if (e.keyCode == 13) {
var range = document.selection.createRange();
range.pasteHTML("<br> ");
range.moveStart("character", 0);
range.moveEnd("character", -1);
range.select();
return false;
}
if(e.keyCode==13){
var range=document.selection.createRange();
range.pasteHTML(“
”);
范围.moveStart(“字符”,0);
范围.moveEnd(“字符”,-1);
range.select();
返回false;
}
使用Internet Explorer时,请考虑使用
。你可能不想在Chrome上这样做,因为焦点看起来很有趣。您可能需要实现自己的onfocus
和onblur
代码。即按Enter键时用
标记绑定文本节点。要实现换行,请按住Shift键并输入。Firefox在按Enter键时添加了一个
标记。要使行为在两种浏览器中通用,可以执行以下操作:
假设以下标记:
<div id="editableDiv" contentEditable="true"></div>
注意:这个脚本是在jQuery<1.9之前使用的,用于使用不推荐的$。浏览器
很好-即使是可用的WYSIWYG编辑器也可以提供帮助,因为他们实现了自己的撤销系统。Meta旁白:我通常不愿意发布我自己的赏金的答案,但已经四天没有回应了;我不想看到这些点消失在乙醚中…我认为这是最好的解决方案。由于IE11不再在用户代理中发送“msie”,我们必须为它编写一个全新的案例,包含一系列全新的黑客。。。该死的-让我们做边距的事情吧。我在做客户端编辑器。在可编辑元素中复制和粘贴是非常重要的,因此是否保留换行符也很重要。Contenteditable生成了一些你所见过的最糟糕的html。无论如何,在服务器端清理html都是一个好主意。就这点而言,将html用于客户端标记永远是一个好主意。从长远来看,我们放弃了支持希望从word复制粘贴的客户端,没有人会更高兴:$我同意清理HTML是个好主意,但一旦我清理HTML,您就不能再使用“撤消”菜单撤消更改了!这就是我问题的重点。丹,两点:1。在我建议的方案中,保留了换行符。他们只是在追问事实。2.如果在提交表单之前不进行清理,则将整个撤消队列留给用户。表单提交后不应该保存这些内容。Robusto,我正在尝试在用户点击Enter键的瞬间生成单间隔行,而不会在用户每次点击Enter键时中断撤消。
(function () {
//Initialize _shiftKeyPressed to false
var _shiftKeyPressed = false;
$('#editableDiv').live('keydown', function (e) {
if (e.keyCode == 16) {
// SHIFT key is pressed
_shiftKeyPressed = true;
}
}).live('keyup', function (e) {
if (e.keyCode == 16) {
// SHIFT key is release
_shiftKeyPressed = false;
}
}).live('keypress', function (e) {
if (e.keyCode == 13 && !_shiftKeyPressed && !jQuery.browser.msie) {
// Insert a PARAGRAPH in Firefox instead of a BR
// Ignores SHIFT + ENTER
document.execCommand("insertParagraph", false, true);
}
})
})();