Webkit中的选择范围 (Safari/Chrome)

10

我正在使用content-editable iframe来创建一个JavaScript语法高亮器,其中最重要的一件事就是能够正确缩进代码。

以下代码在Firefox中正常运行:

// Create one indent character
var range = window.getSelection().getRangeAt(0);
var newTextNode = document.createTextNode(Language.tabChar);
range.insertNode(newTextNode);
range.setStartAfter(newTextNode);

它创建一个制表符并将光标移动到字符的右侧。在 Chrome 和 Safari 中,会插入一个字符,但是光标不会移动到其右侧。

我检查了 Chrome 和 Firefox 中的 range 对象,发现 Firefox 的 range 对象比 Chrome 更丰富。我无法找到 Webkit 中 range 对象的任何规范。

如何使此代码适用于 Webkit 和 Firefox?

谢谢!

1个回答

23

无论是Firefox还是WebKit的Range对象都完全符合DOM Range规范。如果Firefox有更多属性,那么它们将是Mozilla自己的扩展,但通常规范提供了您需要的所有内容。

无论如何,问题在于在修改范围后需要重新选择该范围:

// Create one indent character
var sel = window.getSelection();
var range = sel.getRangeAt(0);
var newTextNode = document.createTextNode(Language.tabChar);
range.insertNode(newTextNode);
range.setStartAfter(newTextNode);
sel.removeAllRanges();
sel.addRange(range);

请注意,在早期版本的Safari中(我认为是版本3之前),这不起作用,因为其选择对象不支持getRangeAt。如果需要,我可以提供解决方法。


1
因此,在Firefox中,只需调用range.setStartAfter()即可更新选择内容,无需调用selection.addRange()。然而,Chrome需要addRange()的调用。 - maulik13
1
@maulik13:确实如此。然而,Firefox是唯一能够这样做的浏览器,规范也没有提到这一点,因此我通常建议使用addRange()调用,而不提及这个细节。 - Tim Down
@TimDown 我不确定为什么只有 Firefox 会这样做。我同意你的建议。你的回答对于解决我今天遇到的 Chrome 问题非常有帮助 :) - maulik13
sel.removeAllRanges(); sel.addRange(range); 这救了我的一天! - Son Tr.

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