29

在 Internet Explorer 上,contentEditable DIV 会在<p></p>您每次按 Enter 时创建一个新段落 ( ),而 Firefox 会创建一个<br/> 标签。

正如这里所讨论的,可以使用 JavaScript 拦截 Enter keyPress 并使用 range.pasteHTML 创建一个<br/>代替。但是这样做会破坏撤消菜单;一旦您按 Enter 键,您就无法再撤消超过该点。

如何强制 contentEditable 元素在 Enter 上创建单个换行符而不破坏 Undo?

4

7 回答 7

17

不是一个确切的解决方案,而是另一种解决方法。如果您使用标记:

<div contenteditable="true">
<div>
content
</div>
<div>

然后按下enter将创建新div标签而不是p标签。

于 2010-02-16T00:19:55.870 回答
5

当你按下回车键时按住 shift 键,不要在整个段落中按住它。默认情况下,这种行为在 Firefox 中是相同的,给定一个包含段落的 contenteditable 区域:即

<div contenteditable="true">
    <p>If you are typing here</p>
<div>
于 2010-02-16T14:52:07.713 回答
4

大概您要将可编辑的内容发布回服务器。因此,您不应该真正关心用户编辑时是否有段落或中断标记,因为您可以在提交之前(或在服务器上,如果您愿意)解析 HTML 并用中断替换段落实例。这可以让 UNDO 队列为用户运行,但可以让您的 HTML 尽可能干净。

我将进一步假设您将确切知道哪些 DIV 元素将是 contentEditable。在提交表单之前,您可以通过如下函数运行每个 contentEditable div:

function cleanContentEditableDiv(div) {
  var htmlString = div.innerHTML;
  htmlString     = htmlString.replace(/<\/p>/gim,"<br/>");
  htmlString     = htmlString.replace(/<p>/gim,"");
  return htmlString;
}

然后你在一个循环中调用它(它遍历所有 contentEditable DIV,使用我将称为 ceDivs 的数组),如下所示:

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)) 加上尽可能多的空格  空间运行中留下的实体。

于 2010-02-16T13:53:29.877 回答
4

使用<BR>代替<P>(在 IE9 中测试。可能nbsp;在 之后的旧版本中需要<BR> (pasteHTML("<br>&nbsp;"))

在 keydown 事件中使用它:

if (e.keyCode == 13) {
 var range = document.selection.createRange();
 range.pasteHTML("<br> ");
 range.moveStart("character", 0);
 range.moveEnd("character", -1);
 range.select();
 return false;
}
于 2011-07-27T13:02:51.907 回答
2

可能无法做到这一点。但是,可以通过使用 CSS 删除段落标签周围的内置边距,使<p>标签看起来像单行换行符:

p { margin: 0; }

这种方法有一个缺点:如果用户需要在 contentEditable 元素中复制/粘贴文本,则文本可能会在元素内显示为单行距,但在元素外显示为双行距。

更糟糕的是,至少在某些情况下,IE 会在粘贴过程中自动检测双换行符,并用<p>标签替换它们;这会弄乱粘贴文本的格式。

于 2010-02-14T21:40:44.340 回答
1

IE 在按键时将文本节点与<p>标签绑定。Enter实现换行Shift+ Enter。Firefox在按键时添加了一个<br>标签。Enter要使两种浏览器的行为通用,您可以执行以下操作:

假设以下标记:

<div id="editableDiv" contentEditable="true"></div>

Javascript [假设下面的代码在一个函数闭包中,这样你就不会用全局变量使页面膨胀]:

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

注意:此脚本在 jQuery < 1.9 之前使用,已弃用$.browser

于 2012-03-26T12:12:02.513 回答
0

<span contenteditable="true"></span>在使用 Internet Explorer 时考虑使用。您可能不想在 Chrome 上执行此操作,因为焦点看起来很有趣。您可能希望实现自己的onfocus代码onblur

于 2011-12-13T18:44:19.093 回答