Discontigious Selection не поддерживается ошибка в Google Chrome и хром

Я работаю над приложением для заметок, где я должен хранить выбранные пользователем ключевые слова или слова или контент. Я использую методы 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., когда я храню несколько элементов в массиве диапазонов и нажимаю кнопку "Показать сохраненные выборы".

Помощь будет оценена по достоинству. И, пожалуйста, предложите мне, если есть другие альтернативы, которые выполняют эту задачу по закладок.

Ответ 2

Здесь единственный возможный способ сделать это, что я смог придумать:

Оберните выделение в <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>

Ответ 3

FYI. Я получал аналогичную ошибку при переходе моей собственной функции "копировать в буфер обмена" . Я не собираюсь обращаться к OP предоставленному коду, но я расскажу вам, как я исправил его в своем собственном коде.

Воспроизведите:

  • Скопируйте другой текст на страницу в буфер обмена, например. "Foo".
  • Вставить текст где-нибудь. Он выводит "foo".
  • Нажмите кнопку "копировать в буфер обмена" , которая копирует, например. "Бар".
  • Вставить текст где-нибудь.
Ожидается

:

"bar" выводится.

Actual:

"Отключенный выбор не поддерживается"

Fix:

Вызовите window.getSelection().removeAllRanges() в start вашего обработчика событий "копировать в буфер обмена" . "Несравненный" означает "не подключен". Поэтому я предполагаю, что браузер копирует первый диапазон (node содержащий "foo" ), а затем разозлился, когда вы пытаетесь выбрать другой диапазон, который не находится рядом с первым node.