Ответ 1
Запись
window.getSelection().removeAllRanges();
непосредственно перед созданием диапазона.
https://bugs.chromium.org/p/chromium/issues/detail?id=399791
Я работаю над приложением для заметок, где я должен хранить выбранные пользователем ключевые слова или слова или контент. Я использую методы 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. Я могу выбрать несколько вещей один за другим и снова показать выбранный контент, но на хром и хром я получаю ошибку Discontiguous selection is not supported.
, когда я храню несколько элементов в массиве диапазонов и нажимаю кнопку "Показать сохраненные выборы".
Помощь будет оценена по достоинству. И, пожалуйста, предложите мне, если есть другие альтернативы, которые выполняют эту задачу по закладок.
Запись
window.getSelection().removeAllRanges();
непосредственно перед созданием диапазона.
https://bugs.chromium.org/p/chromium/issues/detail?id=399791
Здесь единственный возможный способ сделать это, что я смог придумать:
Оберните выделение в <span style="background: Highlight;">...</span>
.
Но обратите внимание:
window.onmousedown
, а не window.onclick
, потому что onclick
запускается после, нажатие любой кнопки, поэтому при нажатии кнопки "Показать сохраненные выборы" новый выбор будет создаваться, тем самым уничтожая тот, который должен был быть захвачен.Следующий код (fiddle) - лучшее, что я смог сделать:
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.<br><br>
<button onclick="storeSelection();">Store the selection</button>
<button onclick="clearStoredSelections();">Clear stored selections</button>
<button onclick="showStoredSelections();">Show stored selections</button>
FYI. Я получал аналогичную ошибку при переходе моей собственной функции "копировать в буфер обмена" . Я не собираюсь обращаться к OP предоставленному коду, но я расскажу вам, как я исправил его в своем собственном коде.
Воспроизведите:
:
"bar" выводится.
Actual:
"Отключенный выбор не поддерживается"
Fix:
Вызовите window.getSelection().removeAllRanges()
в start вашего обработчика событий "копировать в буфер обмена" . "Несравненный" означает "не подключен". Поэтому я предполагаю, что браузер копирует первый диапазон (node содержащий "foo" ), а затем разозлился, когда вы пытаетесь выбрать другой диапазон, который не находится рядом с первым node.