Javascript 在内联元素中使用range.expand(';word';)时,范围的boundingClientRect计算不正确

Javascript 在内联元素中使用range.expand(';word';)时,范围的boundingClientRect计算不正确,javascript,html,range,getboundingclientrect,Javascript,Html,Range,Getboundingclientrect,我正在使用一个chrome translate扩展插件,当按住ctrl键几秒钟时,扩展插件会将单词放在光标下,进行翻译,然后将结果显示在单词顶部 在处理获取光标下的单词时,我首先需要创建光标下单词的范围 如果光标位于单词“words”下,则工作正常。但是,当光标位于单词“sample”下时,在调用range.expand('word')后,客户端rect是错误的,客户端rect的宽度应该是“sample”的宽度,但是,它是“sample words”的宽度 这里我还包括一个jsfiddle 这是

我正在使用一个chrome translate扩展插件,当按住ctrl键几秒钟时,扩展插件会将单词放在光标下,进行翻译,然后将结果显示在单词顶部

在处理获取光标下的单词时,我首先需要创建光标下单词的范围

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

这里我还包括一个jsfiddle


这是
range.expand('word')
的问题吗?如何解决?还是不使用
range.expand('word')
,有什么方法可以实现这一点?非常感谢您的帮助!另外,我使用的是chrome 39。

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

控制台还显示,
range.expand()
,这一直是一种仅限于WebKit的非标准方法,已经被弃用,取而代之的是,不幸的是,在实践中使用它有点麻烦。下面是一个使用
选择的修订示例。修改
,它确实解决了您的问题:


使用
caretRangeFromPoint
方法可以大大简化我的工作!!以及您使用
选择的解决方法。如果选择中不包括单词的以下空格,则“修改”
非常有效。@timdown如何在调用
选择后删除单词的以下空格。修改('extend'、'forward'、'word')
@TimI发现调用
range.expand('word')
后,范围的属性(startOffset、endOffset、startContainer、endContainer)似乎设置正确。我还发现了以下内容:。
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);
};
<p>click the <a href='#'>sample words</a> here</p>