В Firefox изменение диапазона, клонированного из выделения, очищает выделение в первый раз - PullRequest
2 голосов
/ 20 марта 2009
<script>
    var is_gecko = /gecko/i.test(navigator.userAgent);
    var is_ie    = /MSIE/.test(navigator.userAgent);

    function insertNodeAtSelStart()
    {
        if(is_gecko)
        {
            var S = window.getSelection();
            if(!S.isCollapsed)
            {
                var R = S.getRangeAt(0);
                var R1 = R.cloneRange();
                var NN = document.createElement("startMarker");
                R1.insertNode(NN);
                NN.parentNode.removeChild(NN);
            }
        }

        if(is_ie)
        {
            // IE-specific code
        }
    }
</script>

<div>
    <span>one two three</span>
</div>

<input type="button" value="Insert node at selection start" onclick="insertNodeAtSelStart();" />

При первом нажатии кнопки после загрузки страницы и выделения некоторого текста Firefox очищает выделение. Впоследствии это не так. Это ошибка в моем коде или в Firefox?

Ответы [ 2 ]

3 голосов
/ 20 марта 2009

Firefox очищает выделение, когда вы нарушаете его, успешно вставляя узел в начальную точку.

Для меня второй щелчок иногда (в зависимости от того, какой диапазон текста выделен) завершается неудачно с:

Error: uncaught exception: [Exception... "Index or size is negative or greater than the allowed amount"  code: "1" nsresult: "0x80530001 (NS_ERROR_DOM_INDEX_SIZE_ERR)"  location: "..."]

при вызове insertNode. Поскольку вставка не удалась, выбор не очищен. Предположительно, это то, что происходит с вами - проверьте консоль ошибок.

Эта ошибка, по-видимому, является ошибкой Firefox. Я не могу точно отследить точные условия, которые его вызывают, но это связано с тем, какие границы узлов находятся в выделении.

Я могу заставить ваш пример всегда работать (и очищать выделение), вызвав document.body.normalize (), чтобы вернуть весь контент диапазона в один узел Text после того, как он был разделен циклом вставки / удаления. 1012 *

2 голосов
/ 20 марта 2009

Действительно, вы наткнулись на некрасивую ошибку Gecko, которая продолжает ползти к жизни в течение слишком многих лет :( И да, последняя версия разработки все еще представляет эту ошибку.

В любом случае, если вы не хотите ждать исправления от Mozilla, более простой / более быстрый обходной путь - свернуть диапазон перед вставкой нового узла.

Для соответствия вот (как-то упрощенно) пример, используемый для тестирования вашего кода:

<p id="para">select two or more letters, then </p>
<input id="butt" type="button" value="click me">
<script type="text/javascript">
  if (!window.getSelection)
    throw new Error("MSIE, you're not welcome!");

  var marker = document.createElement('span');
  marker.style.color = '#6C6';
  marker.appendChild(document.createTextNode('|'));

  function insertNodeAtSelStart() {
    // window.getSelection().getRangeAt(0).insertNode(marker.cloneNode(true));
    var r = window.getSelection().getRangeAt(0);
    var n = marker.cloneNode(true);
    r.collapse(true); // workaround for Gecko :(
    r.insertNode(n);  // Gecko sometimes(?!) fails with NS_ERROR_DOM_INDEX_SIZE_ERR
  }
  document.getElementById('butt').onclick = insertNodeAtSelStart;
</script>

OT, это не "is _ gecko", "is _ not _ ie" было бы более уместно, так как этот код должен работать, как и ожидалось, во всех браузерах, кроме MSIE;

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...