我正在开发一个书签应用程序,我必须存储用户选择的关键字或文字或内容。我使用createRange()和addRange()javascript方法创建范围,然后由用户找出所选元素/内容。我为此编写的代码如下。
<head>
<script type="text/javascript">
var storedSelections = [];
function StoreSelection () {
if (window.getSelection) {
var currSelection = window.getSelection ();
for (var i = 0; i < currSelection.rangeCount; i++) {
storedSelections.push (currSelection.getRangeAt (i));
}
currSelection.removeAllRanges ();
} else {
alert ("Your browser does not support this example!");
}
}
function ClearStoredSelections () {
storedSelections.splice (0, storedSelections.length);
}
function ShowStoredSelections () {
if (window.getSelection) {
var currSelection = window.getSelection ();
currSelection.removeAllRanges ();
for (var i = 0; i < storedSelections.length; i++) {
currSelection.addRange (storedSelections[i]);
}
} else {
alert ("Your browser does not support this example!");
}
}
</script>
</head>
<body>
Select some content on this page and use the buttons below.<br /> <br />
<button onclick="StoreSelection ();">Store the selection</button>
<button onclick="ClearStoredSelections ();">Clear stored selections
</button>
<button onclick="ShowStoredSelections ();">Show stored selections</button>
</body>
此代码在Firefox上完美运行。我可以逐个选择多个内容,并且能够再次显示所选内容但是在chrome和chromium上,当我在范围数组中存储多个元素并单击show stored selections按钮时,我收到Discontiguous selection is not supported.
错误。
帮助将不胜感激。如果有其他替代方案可以完成此书签任务,请建议我。
答案 0 :(得分:9)
写
window.getSelection().removeAllRanges();
在创建范围之前。
https://bugs.chromium.org/p/chromium/issues/detail?id=399791
答案 1 :(得分:6)
这是我能够做到这一点的唯一可行方法:
将选择内容包裹在<span style="background: Highlight;">...</span>
。
但请注意:
window.onmousedown
而不是window.onclick
,因为{/ 1}}在按下任何按钮后触发,因此当您按下&#34;显示时存储的选择&#34;按钮,将创建一个新的选择,从而摧毁应该被捕获的那个。以下代码(fiddle)是我能做的最好的代码:
onclick
&#13;
var storedSelections = [];
var simulatedSelections = [];
window.onmousedown = clearSimulatedSelections;
function storeSelection()
{
if(window.getSelection)
{
var currSelection = window.getSelection();
for(var i = 0; i < currSelection.rangeCount; i++)
{
storeRecursive(currSelection.getRangeAt(i));
}
currSelection.removeAllRanges();
}
else
{
alert("Your browser does not support this example!");
}
}
function storeRecursive(selection, node, started)
{
node = node || document.body;
started = started || false;
var nodes = node.childNodes;
for(var i = 0; i < nodes.length; i++)
{
if(nodes[i].nodeType == 3)
{
var first = nodes[i] == selection.startContainer;
var last = nodes[i] == selection.endContainer;
if(first)
{
started = true;
}
if(started)
{
var sel = selection.cloneRange();
if(!first)
{
sel.setStartBefore(nodes[i]);
}
if(!last)
{
sel.setEndAfter(nodes[i]);
}
storedSelections.push(sel);
if(last)
{
return false;
}
}
}
else
{
started = storeRecursive(selection, nodes[i], started);
}
}
return started;
}
function clearStoredSelections()
{
storedSelections = [];
}
function showStoredSelections()
{
if(window.getSelection)
{
var currSelection = window.getSelection();
currSelection.removeAllRanges();
for(var i = 0; i < storedSelections.length; i++)
{
var node = document.createElement("span");
node.className = "highlight";
storedSelections[i].surroundContents(node);
simulatedSelections.push(node);
}
}
else
{
alert("Your browser does not support this example!");
}
}
function clearSimulatedSelections()
{
for(var i = 0; i < simulatedSelections.length; i++)
{
var sec = simulatedSelections[i];
var pn = sec.parentNode;
while(sec.firstChild)
{
pn.insertBefore(sec.firstChild, sec);
}
pn.removeChild(sec);
}
simulatedSelections = [];
}
&#13;
.highlight
{
background: Highlight;
}
&#13;
适用于Firefox,Safari和Chrome,但有以下缺点:
但是,我怀疑除了Firefox之外的其他浏览器有什么更好的方法,甚至是Firefox has a ticket to drop discontiguous selections。
答案 2 :(得分:3)
仅供参考我在将自己的#34;副本复制到剪贴板时遇到了类似的错误。特征。我不打算解决OP提供的代码,但我会告诉您如何在我自己的代码中修复它。
重现:
预期:
&#34;杆&#34;输出。
实际值:
&#34;不支持不连续的选择&#34;
修正:
在你的&#34; <#>复制到剪贴板&#34;的开始处致电window.getSelection().removeAllRanges()
事件处理程序&#34;不连续&#34;意味着&#34;没有连接&#34;。所以我的猜测是浏览器复制第一个范围(包含&#34; foo&#34;的节点),然后当你尝试选择另一个不在第一个节点旁边的范围时生气。