内容可编辑区域中的选择更改事件

6

我可编辑元素的标记如下:

<iframe class="rich_text">
<html style="background:none transparent;">
    <head></head>
    <body contenteditable="true"></body>
</html>
</iframe>

内容可编辑的body元素是否有选择变更事件?这样我就可以检测所选文本块是否具有粗体/下划线等。

我尝试了一些事件处理程序(jQuery),但没有成功:

var richText = $(".rich_text"),
richTextDoc = richText.contents()[0],
richTextBody = richText.contents().find("body");

// Enable Design mode.
richTextDoc.open();
richTextDoc.write("");
richTextDoc.close();
richTextDoc.designMode = "on";

// Binds selection change event
$(richTextDoc).bind("select", function() { ... });
$(richTextDoc).bind("selectstart", function() { ... });
richTextBody .bind("select", function() { ... });
richTextBody .bind("selectstart", function() { ... });
3个回答

6

更新2017+

现在有一种跨浏览器的方法。最近的WebKit / Blink浏览器(例如Chrome,Safari,Opera)支持selectionchange,并且自Firefox 43版本以来支持它。

旧答案

没有一种跨浏览器的方法可以检测选择更改。IE和最近的WebKit浏览器(例如Chrome和Safari)支持文档上的selectionchange事件。Firefox和Opera没有这样的事件,您只能检测通过键盘和鼠标事件进行的选择更改,这是不令人满意的(例如,无法检测上下文或编辑菜单中的“全选”)。


多么悲伤 :-( 未来有没有希望解决这个问题?contenteditable 太差了... - Frodik
2
@Frodik:有一个W3C的公开bug来规范它:https://www.w3.org/Bugs/Public/show_bug.cgi?id=13952。如果你大惊小怪,事情有时会有所进展,尽管浏览器实现者在那里拥有最大的影响力。 - Tim Down

5
假设你的iframe内容来自同一域名,你可以使用以下代码:
$('.rich_text').contents()
  .find('body')
  .bind('selectstart', function(){});

正如您可以从这里看到的那样,当选中元素时,selectstart事件会被正确触发。


"selectstarts" 可以正常工作,但仅限于文档元素。一开始它不能正常工作的原因是我在代码后面再次调用了 richTextDoc.open();,如果在此之后调用 open(),事件处理程序将不起作用。谢谢 :) http://jsfiddle.net/6e8cR/6/ - Bananakilo
2
当使用键盘选择更改时(使用箭头键滚动插入符号),这也不起作用。 - marchaos

1
对于火狐浏览器,https://developer.mozilla.org/zh-CN/docs/XPCOM_Interface_Reference/NsIEditor 提供了编辑器的观察者。假设需要基于 XPCOM 的“特权”。 除了鼠标和键盘跟踪之外,火狐浏览器上的其他解决方案: 在所有/关注节点/元素(文本?)的“焦点”和“模糊”事件上,比较焦点事件时的节点内容和离开事件(即使是窗口关闭或类似操作)时的节点内容,并设置 YOUR 或 '_moz_dirty' 等脏属性(取决于应该为谁/什么浏览器服务,还可以根据需要创建许多不同的脏属性)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接