强制 IE contentEditable 元素在 Enter 键上创建换行符,而不破坏撤消
在 Internet Explorer 上,每次按 Enter 时,contentEditable DIV 都会创建一个新段落 (),而 Firefox 则会创建一个
> 标签。
正如所讨论的 here,可以使用 JavaScript 拦截 Enter keyPress 并使用 range.pasteHTML 创建一个
来代替。但这样做会破坏撤消菜单;一旦按下 Enter 键,您将无法再撤消该点之后的操作。
如何强制 contentEditable 元素在 Enter 上创建单行中断而不破坏 Undo?
On Internet Explorer, a contentEditable DIV creates a new paragraph (<p></p>
) each time you press Enter whereas Firefox creates a <br/>
tag.
As discussed here, it is possible to use JavaScript to intercept the Enter keyPress and use range.pasteHTML to create a <br/>
instead. But doing this breaks the Undo menu; once you hit Enter, you can no longer Undo past that point.
How can I force the contentEditable element to create single line breaks on Enter without breaking Undo?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
不是确切的解决方案,而是另一种解决方法。如果您使用标记:
那么按 enter 将创建新的
div
标记,而不是p
标记。Not an exact solution, but another workaround. If you use the markup:
Then pressing enter will create new
div
tags instead ofp
tags.当您按 Enter 键进行中断时,请按住 Shift 键,不要按住它来显示整个段落。默认情况下,此行为在 Firefox 中是相同的,假设内容可编辑区域包含一个段落:即
Hold down shift when you press enter for breaks, don't hold it down for full paragraphs. This behaviour is the same by default in Firefox, given a contenteditable area containing a paragraph: i.e.
想必您要将可编辑的内容发布回服务器。因此,您不应该真正关心用户编辑时是否有段落或分隔标记,因为您可以在提交之前(或在服务器上,如果您愿意)解析 HTML 并用分隔符替换段落实例。这可以让 UNDO 队列保持对用户的运行状态,同时让您的 HTML 变得如您所愿地干净。
我将进一步假设您将确切地知道哪些 DIV 元素将是内容可编辑的。在提交表单之前,您可以通过这样的函数运行每个 contentEditable div:
然后在循环中调用它(它迭代所有 contentEditable DIV,使用一个我将称为 ceDivs 的数组),如下所示:
:
然后 对此(特别是如果您不想在提交时正确执行此操作),可能是在您喜欢的任何其他时间(onblur,无论如何)清理每个此类 div 的内容,并将每个 ceDiv 的内容分配给其自己的不可见内容供以后提交的表单元素。与上面您自己的 CSS 建议结合使用,这可能对您有用。它不会保留您的字面要求(即,它不会让 Javascript 使 IE 的行为不同于它在幕后编码的行为),但对于所有实际目的,效果是相同的。用户得到他们想要的,你也得到你想要的。
当您这样做时,您可能还想清除 IE 中的空格字符串。如果用户输入多个空格(有些人在句号后仍然这样做),IE 插入的不是 [space][space] 而是 [space] ,一个初始空格字符 (String.fromCharCode(32)) 加上尽可能多空间运行中剩余的实体。
Presumably you are going to post the editable content back to a server. Therefore, you shouldn't really care whether you have paragraph or break tags in place while the user is editing, because you can parse the HTML before submission (or on the server, if you like) and replace instances of paragraphs with breaks. This keeps the UNDO queue in operation for the user, but lets you have your HTML as clean as you want it.
I'll further presume that you're going to know exactly which DIV elements are going to be contentEditable. Before the form is submitted, you can run each contentEditable div through a function like this:
And you call this in a loop (which iterates through all contentEditable DIVs, using an array I will call ceDivs), like this:
and then:
An improvement on this (especially if you don't want to do this right at submit time), might be to clean the contents of each such div any other time you like (onblur, whatever) and assign the contents of each ceDiv to its own invisible form element for later submission. Used in combination with your own CSS suggestion above, this might work for you. It doesn't preserve your literal requirements to the letter (i.e., it doesn't get Javascript to make IE behave differently than it has been coded under the covers to behave) but for all practical purposes the effect is the same. The users get what they want and you get what you want.
While you're at it you may also want to clean space strings in IE as well. If the user types multiple spaces (as some still do after periods), what is inserted by IE is not [space][space] but [space] , an initial space character (String.fromCharCode(32)) plus as many entities as there are left in the space run.
使用
代替(在IE9中测试。在
<之后的旧版本中可能需要
nbsp;
;BR>(pasteHTML("
)"))
在 keydown 事件上使用它:
Use
<BR>
instead of<P>
(Tested in IE9. Maybenbsp;
is needed in older versions after<BR>
(pasteHTML("<br> "))
)Use it on keydown event:
要做到这一点可能是不可能的。 ,通过使用 CSS 删除段落标签周围的内置边距,可以使
标签看起来像单个换行符:
但是 这种方法的缺点:如果用户需要在 contentEditable 元素中复制/粘贴文本,则文本可能在元素内部显示为单倍行距,但在元素外部显示为双倍行距。
更糟糕的是,至少在某些情况下,IE 会在粘贴过程中自动检测双换行符,并将其替换为
标签;这会弄乱粘贴文本的格式。
It may be impossible to get this right. However, it is possible to make the
<p>
tags look like single line breaks, by removing the built-in margin around paragraph tags, using CSS:There is a drawback to this approach: if the user needs to copy/paste text in the contentEditable element, the text may appear to be single-spaced inside the element but double-spaced outside the element.
Worse, in at least some cases, IE will automatically detect double-line breaks during paste, replacing them with
<p>
tags; this will mess up the formatting of the pasted text.IE 在按 Enter 按键时将文本节点与
标记绑定。要实现换行Shift+Enter。 Firefox 在 Enter 按键上添加了一个
标记。要使行为在两个浏览器中通用,您可以执行以下操作:假设以下标记:
Javascript [假设以下代码位于函数闭包中,这样就不会使用全局变量使页面膨胀]:
注意: 这个脚本早于 jQuery < 1.9 使用已弃用的
$.browser
IE binds the text node with a
<p>
tag on Enter key press. To achieve a line break Shift+Enter. Firefox adds a<br>
tag on Enter key press. To make the behavior common across both the browsers, you can do the following:Assume the following markup:
Javascript [assume the below code is in a function closure so that you don't bloat the page with globals]:
Note: this script is prior to jQuery < 1.9 for the use of the deprecated
$.browser
使用 Internet Explorer 时,请考虑使用
。您可能不想在 Chrome 中执行此操作,因为焦点看起来很有趣。您可能想要实现自己的
onfocus
和onblur
代码。Consider using
<span contenteditable="true"></span>
when using Internet Explorer. You may not want to do this with Chrome because the focus looks funny. You will probably want to implement your ownonfocus
andonblur
code.