这当然不是一项简单的任务,因为您面临两个主要问题,即在当前文档中定位文本,然后在后续页面加载时再次找到它。如果您的页面内容可能发生变化,问题会更加复杂,因为您甚至不能依靠文本的相对位置来保持不变。
考虑到所需的努力,您可能想考虑这是否是您尝试完成的任何事情的最佳方法,但这里有一些可能会让您朝着正确的方向开始:
function getSelection() {
var selection, position;
if (window.getSelection) {
selection = window.getSelection();
if (selection && !selection.isCollapsed) {
position = {
'offset': selection.anchorOffset,
'length': selection.toString().length,
// We're assuming this will be a text node
'node': selection.anchorNode.parentNode
};
}
} else if (document.selection) {
selection = document.selection.createRange();
if (selection && selection.text.length) {
var text = selection.parentElement().innerText,
range = document.body.createTextRange(),
last = 0, index = -1;
range.moveToElementText(selection.parentElement());
// Figure out which instance of the selected text in the overall
// text is the correct one by walking through the occurrences
while ((index = text.indexOf(selection.text, ++index)) !== -1) {
range.moveStart('character', index - last);
last = index;
if (selection.offsetLeft == range.offsetLeft && selection.offsetTop == range.offsetTop) {
break;
}
}
position = {
'offset': index,
'length': selection.text.length,
'node': selection.parentElement()
};
}
}
return position;
}
以及再次选择文本的方法:
function setSelection(position) {
if (!position || !position.node) {
return;
}
var selection, range, element;
if (document.createRange) {
element = position.node.childNodes[0];
range = document.createRange();
range.setStart(element, position.offset);
range.setEnd(element, position.offset + position.length);
selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);
} else if (document.body.createTextRange) {
range = document.body.createTextRange();
range.moveToElementText(position.node);
range.collapse(true);
range.move('character', position.offset);
range.moveEnd('character', position.length);
range.select();
}
}
这段代码做了一个相当幼稚的假设,即选定的文本都驻留在同一个 DOM 元素中。如果用户选择任意文本,则很有可能不会出现这种情况。
鉴于Selection object 使用anchorNode 和focusNode 属性解决了这个问题,您可以尝试解决这个问题,但在Internet Explorer 中处理TextRange object 可能会有点问题。
还有一个问题是如何跨页面请求跟踪position.node 值。在我的 jsFiddle sample 中,我使用了 selector-generating jQuery function 的略微修改版本来生成一个选择器字符串,该字符串可以保存并用于稍后重新选择正确的节点。请注意,该过程相对简单,因此您可以在不使用 jQuery 的情况下轻松完成 - 在这种情况下只是碰巧节省了一些精力。
当然,如果您在访问之间更改 DOM,这种方法可能会相当不稳定。如果你不是,我觉得它可能是更可靠的选择之一。