这个答案可能对您来说太晚了,但我面临类似的问题,并希望在此处记录它,因为它是Google上的第一次搜索。
要重申一下,问题是你想只从用户选择拍摄范围对象和环绕它与一个样式的div,像这样:
function highlightSelection() {
var userSelection = window.getSelection().getRangeAt(0);
highlightRange(userSelection);
}
function highlightRange(range) {
var newNode = document.createElement("div");
newNode.setAttribute(
"style",
"background-color: yellow; display: inline;"
);
range.surroundContents(newNode);
}
但作为原始亲本的状态,这是不安全的。如果选择不跨越元素边界,它将起作用,但如果由用户选择创建的范围是跨越HTML标记边界的不安全范围,则会引发DOM错误。
溶液是产生较小的范围内的物体,其中没有一个单独的交叉元件阻挡的阵列,但是其共同覆盖由用户选择的范围。这些安全范围中的每一个都可以像上面那样突出显示。
function getSafeRanges(dangerous) {
var a = dangerous.commonAncestorContainer;
// Starts -- Work inward from the start, selecting the largest safe range
var s = new Array(0), rs = new Array(0);
if (dangerous.startContainer != a)
for(var i = dangerous.startContainer; i != a; i = i.parentNode)
s.push(i)
;
if (0 < s.length) for(var i = 0; i < s.length; i++) {
var xs = document.createRange();
if (i) {
xs.setStartAfter(s[i-1]);
xs.setEndAfter(s[i].lastChild);
}
else {
xs.setStart(s[i], dangerous.startOffset);
xs.setEndAfter(
(s[i].nodeType == Node.TEXT_NODE)
? s[i] : s[i].lastChild
);
}
rs.push(xs);
}
// Ends -- basically the same code reversed
var e = new Array(0), re = new Array(0);
if (dangerous.endContainer != a)
for(var i = dangerous.endContainer; i != a; i = i.parentNode)
e.push(i)
;
if (0 < e.length) for(var i = 0; i < e.length; i++) {
var xe = document.createRange();
if (i) {
xe.setStartBefore(e[i].firstChild);
xe.setEndBefore(e[i-1]);
}
else {
xe.setStartBefore(
(e[i].nodeType == Node.TEXT_NODE)
? e[i] : e[i].firstChild
);
xe.setEnd(e[i], dangerous.endOffset);
}
re.unshift(xe);
}
// Middle -- the uncaptured middle
if ((0 < s.length) && (0 < e.length)) {
var xm = document.createRange();
xm.setStartAfter(s[s.length - 1]);
xm.setEndBefore(e[e.length - 1]);
}
else {
return [dangerous];
}
// Concat
rs.push(xm);
response = rs.concat(re);
// Send to Console
return response;
}
然后可以对(出现)强调用户选择,这个修改后的代码:
function highlightSelection() {
var userSelection = window.getSelection().getRangeAt(0);
var safeRanges = getSafeRanges(userSelection);
for (var i = 0; i < safeRanges.length; i++) {
highlightRange(safeRanges[i]);
}
}
需要注意的是你“,可能需要一些发烧友CSS使许多用户可以一起看起来不同的元素。我希望最终这可以帮助互联网上的其他疲惫的灵魂!
这无疑是最好的主意。很好的答案,但是事后再打开`designMode`确实是个好主意。 – 2010-01-11 21:18:51
尽管帖子已经很老了,但我仍然认为这是我现在可以找到的最佳解决方案 – raoulinski 2014-08-28 15:14:38