Google Chrome和Chrome不支持“Discontigious Selection”错误

我正在开发一个书签应用程序,我必须存储用户选择的关键字或单词或内容。 我使用createRange()和addRange()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!"); } }    Select some content on this page and use the buttons below.

此代码在Firefox上完美运行。 我可以逐个选择多个内容,并且能够再次显示所选内容,但是在chrome和chromium上我得到的Discontiguous selection is not supported. 当我在范围数组中存储多个元素并单击show stored selections按钮时出错。

帮助将不胜感激。 如果有其他替代方案可以完成此书签任务,请建议我。

 window.getSelection().removeAllRanges(); 

在创建范围之前。

https://bugs.chromium.org/p/chromium/issues/detail?id=399791

这是我能够提出的唯一可能的方法:

将选择包装在...

但请注意:

  • 显然,只要选择了其他任何东西,你就必须再次删除这些跨度,但这不应该太困难。 但是,您应该使用window.onmousedown而不是window.onclick ,因为按下任何按钮触发onclick ,因此当按下“显示存储的选择”按钮时,将创建一个新的选择,从而摧毁那个是应该被捕获。
  • 删除或替换存储选择开始或结束的任何元素将使该选择无效,因此单击“显示存储的选择”时,不会显示任何内容。
  • 如果选择跨越多个元素,则需要将每个元素拆分为一个选择,否则插入跨度将失败或将其他元素(如按钮)切成两半。

以下代码( 小提琴 )是我能做的最好的:

 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 = []; } 
 .highlight { background: Highlight; } 
 Select some content on this page and use the buttons below.

仅供参考我在滚动自己的“复制到剪贴板”function时遇到了类似的错误。 我不会解决OP提供的代码,但我会告诉你我是如何在我自己的代码中修复它的。

复制:

  1. 将页面上的其他文本复制到剪贴板,例如“foo”。
  2. 将文本粘贴到某处。 它输出“foo”。
  3. 单击“复制到剪贴板”按钮,复制例如“bar”。
  4. 将文本粘贴到某处。

预期:

输出“bar”。

实际:

“不支持不连续的选择”

固定:

在“复制到剪贴板”事件处理程序的开头调用window.getSelection().removeAllRanges() 。 “Discontiguous”意味着“没有联系”。 所以我的猜测是浏览器复制第一个范围(包含“foo”的节点),然后当你尝试选择另一个不在第一个节点旁边的范围时生气。