Почему этот JavaScript работает так медленно в IE, когда все, что он делает, это изменяет список выбора? - PullRequest
7 голосов
/ 16 ноября 2010

Я работаю над созданием списка с множественным выбором, в котором вы можете выбрать элементы, а затем нажмите кнопку «Вверх» или «Вниз», что позволит вам изменить порядок элементов в списке.

У меня есть простой автономный пример:

<html>
    <head>
        <title>Example</title>
    <script src="https://www.google.com/jsapi"></script>
    <script>
        google.load('jquery', '1.4.1');
    </script>
    </head>
    <body>
        <select id="selectedDataPoints" multiple="multiple">
            <option>Pig</option>
            <option>Duck</option>
            <option>Dog</option>
            <option>Zebra</option>
            <option>Snake</option>
            <option>Giraffe</option>
            <option>Cow</option>
        </select>
    <input type="button" id="btnReorderUp"  value="Up" />
    <input type="button" id="btnReorderDown" value="Down" />
    </body>
</html>

<script type="text/javascript">
    var DataPointSelector = (function() {

    var $selectedList = $('#selectedDataPoints');

        $('#btnReorderUp').click(function(e) {
            moveUp();
            e.preventDefault();
        });

        $('#btnReorderDown').click(function(e) {
            moveDown();
            e.preventDefault();
        });

    function moveUp() {
            var select = $selectedList[0];
            for (var i = 1, n = select.options.length; i < n; i++)
                if (select.options[i].selected && !select.options[i - 1].selected)
                select.insertBefore(select.options[i], select.options[i - 1]);
        }

        function moveDown() {
            var select = $selectedList[0];
            for (var i = select.options.length - 1; i > 0; i--)
                if (select.options[i].selected && !select.options[i + 1].selected)
                    select.insertBefore(select.options[i + 1], select.options[i]);           
        }

    } ());
</script>

Однако кнопка «Вверх / Вниз» буквально за 3-8 секунд начинает действовать в IE7 / 8. Первый щелчок иногда будет быстрым, но после этого список выбора будет обновляться новыми позициями (особенно если у вас выбрана пара элементов).

Эта проблема отсутствует в Chrome / FF. Я бы не подумал, что это простое изменение порядка будет таким интенсивным!

Есть ли у кого-нибудь какая-либо информация, которая могла бы помочь мне ускорить функции moveUp / moveDown?!

Ответы [ 2 ]

4 голосов
/ 16 ноября 2010

Вместо перемещения существующих элементов DOM, воссоздайте весь элемент <select>, включая все дочерние элементы для IE.

2 голосов
/ 16 ноября 2010

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

@ Идея Аррона Дигуллы хороша.Но вы также можете минимизировать время процессора следующими изменениями:

function moveUp() {
  var select = $selectedList[0];
  for (var i = 1, n = select.options.length; i < n; i++)
    var selected = select.options[i],
        selectedPrior = select.options[i - 1]; 
        // Don't locate obj/array element more than once
    if (selected.selected && !selectedPrior.selected) {
      select.insertBefore(selected, selectedPrior);
      break; // Since we have found the right elements, don't do 
    }        // any further checking
  }

Добавлено: Хммм, теперь я вижу, что можно выбрать несколько элементов.Итак, вам нужно переместить несколько предметов, да?В этом случае утверждение перерыва не правильно.

Захватывает ли вас слой пользовательского интерфейса IE?IE не обновляет внешний вид экрана до тех пор, пока не закончится поток JS.Обходной путь должен запустить таймер с 0 сек.Это уступит движку рендеринга IE и позволит обновлять экран.

...