我正在开发一个 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。