我已经可以为 safari 和 IE 执行此操作,就像在小提琴中一样:http://jsfiddle.net/cyk8y/(代码有点复杂或/和混乱,但它只是为了让你可以看到我想要的最终结果)。
我从这里获取了主要代码:在绝对位置设置从 A 到 B 的选择范围
在答案的评论中,Tim Down 给了我这些链接:如何使用 JavaScript 在光标下获取单词和从 FF/Webkit 中的像素位置创建一个折叠范围,以帮助我使我的代码在 FF 和谷歌浏览器中工作。
我试过了,但没有成功。
有人可以给我一个示例,从适用于FF和/或Google Chrome(和Opera)的像素坐标中进行选择。
的最新尝试。表面上看起来可以工作,但我不做任何保证:这是一个不平凡的代码块,我还没有彻底测试它。
一旦我整理和测试了它,它很可能会以某种形式出现在我的 Rangy 库中。
现场演示:http://jsfiddle.net/timdown/ABjQP/8/
代码摘录(Firefox 和 Opera 位):
function getNodeIndex(node) {
var i = 0;
while( (node = node.previousSibling) ) {
i++;
}
return i;
}
function getLastRangeRect(range) {
var rects = range.getClientRects();
return (rects.length > 0) ? rects[rects.length - 1] : null;
}
function pointIsInOrAboveRect(x, y, rect) {
return y < rect.bottom && x >= rect.left && x <= rect.right;
}
function positionFromPoint(doc, x, y, favourPrecedingPosition) {
var el = doc.elementFromPoint(x, y);
var range = doc.createRange();
range.selectNodeContents(el);
range.collapse(true);
var offsetNode = el.firstChild, offset, position, rect;
if (!offsetNode) {
offsetNode = el.parentNode;
offset = getNodeIndex(el);
if (!favourPrecedingPosition) {
++offset;
}
} else {
// Search through the text node children of el
main: while (offsetNode) {
if (offsetNode.nodeType == 3) {
// Go through the text node character by character
for (offset = 0, textLen = offsetNode.length; offset <= textLen; ++offset) {
range.setEnd(offsetNode, offset);
rect = getLastRangeRect(range);
if (rect && pointIsInOrAboveRect(x, y, rect)) {
// We've gone past the point. Now we check which side
// (left or right) of the character the point is nearer to
if (rect.right - x > x - rect.left) {
--offset;
}
break main;
}
}
} else {
// Handle elements
range.setEndAfter(offsetNode);
rect = getLastRangeRect(range);
if (rect && pointIsInOrAboveRect(x, y, rect)) {
offset = getNodeIndex(offsetNode);
offsetNode = el.parentNode;
if (!favourPrecedingPosition) {
++offset;
}
break main;
}
}
offsetNode = offsetNode.nextSibling;
}
if (!offsetNode) {
offsetNode = el;
offset = el.childNodes.length;
}
}
return {
offsetNode: offsetNode,
offset: offset
};
}