0

我正在开发一个 chrome 翻译扩展,当按住 ctrl 键几秒钟时,扩展会获取光标下的单词,翻译它,然后在单词的顶部显示结果。

在处理获取光标下的单词时,我首先需要创建光标下单词的范围。我使用下面的代码片段来实现这一点。我参考here。https://stackoverflow.com/a/3710561/4244369

var getRangeAtPoint = function(elem, x, y) {
    if (elem.nodeType == elem.TEXT_NODE) {
        var range = elem.ownerDocument.createRange();
        range.selectNodeContents(elem);
        var currentPos = 0;
        var endPos = range.endOffset;
        while (currentPos + 1 < endPos) {
            range.setStart(elem, currentPos);
            range.setEnd(elem, currentPos + 1);
            var range_rect = range.getBoundingClientRect();
            if (range_rect.left <= x && range_rect.right >= x &&
                range_rect.top <= y && range_rect.bottom >= y) {
                range.expand("word");
                return range;
            }
            currentPos += 1;
        }
    } else {
        for (var i = 0; i < elem.childNodes.length; i++) {
            var range = elem.childNodes[i].ownerDocument.createRange();
            range.selectNodeContents(elem.childNodes[i]);
            var range_rect = range.getBoundingClientRect();
            if (range_rect.left <= x && range_rect.right >= x &&
                range_rect.top <= y && range_rect.bottom >= y) {
                range.detach();
                var computed_range = getRangeAtPoint(elem.childNodes[i], x, y);
                if(computed_range){
                    return computed_range;
                }
            } else {
                range.detach();
            }
        }
    }
    return (null);
};

创建范围后,我可以range.toString()用来获取单词并range.getBoundingClientRect()决定显示结果的位置。它运行良好,直到遇到以下情况:

<p>click the <a href='#'>sample words</a> here</p>

如果光标在“words”这个词下,它可以正常工作。但是,当光标在“sample”这个词下时,调用后range.expand('word')客户端rect是错误的,客户端rect的宽度应该是“sample”的宽度,但是,它是“示例词”的宽度。

我还在这里包含了一个 jsfiddle。https://jsfiddle.net/sangelee/1maqmm89/

是问题range.expand('word')吗?如何解决?或者不是使用range.expand('word'),有什么方法可以实现吗?感谢任何帮助!ps.我正在使用 chrome 39。

4

1 回答 1

0

range.expand()正如您所怀疑的,问题出在 . 此外,将插入符号位置作为范围的代码可以大大简化。示例(仅限 WebKit):

https://jsfiddle.net/e5knrLv8/

控制台还显示,range.expand()一直是仅 WebKit 的非标准方法,已被弃用,取而代之的是Selection.modify(),不幸的是,在实践中使用它有点痛苦。这是一个使用的修改示例Selection.modify,它确实解决了您的问题:

https://jsfiddle.net/e5knrLv8/1/

于 2015-03-09T14:00:55.690 回答