JQuery Hide () и Show () работает слишком медленно в Google Chrome - PullRequest
16 голосов
/ 30 января 2011

У меня есть веб-приложение, которое некорректно работает в Chrome.Отлично работает в Firefox.У меня есть страница с большим количеством пунктов списка, если быть точным, 316.Каждый элемент списка содержит большое количество HTML.Моя проблема в том, что я хочу скрыть или показать эти элементы списка.

У меня есть тестовая страница на jsFiddle, чтобы показать проблему, с которой я столкнулся.Я разложил HTML-страницу до одного неупорядоченного списка, чтобы вместить все 316 элементов списка.У меня есть две кнопки, которые просто вызывают JQuery скрыть или показать при нажатии.Опять же, это работает быстро в Firefox, Opera, даже IE, очень хорошо в Safari, но в Google Chrome это может занять более 30 секунд, в результате чего открывается диалоговое окно с вопросом, хотите ли вы убить страницу, потому что скрипт выполняется долго.

Вот ссылка на jsFiddle

http://jsfiddle.net/oumichaelm/UZCZc/3/embedded/result/

спасибо за любой вклад.JMM

Ответы [ 3 ]

11 голосов
/ 30 января 2011

Похоже, что это не имеет ничего общего с jQuery, и это просто проблема с Chrome, скрывающим родительский элемент, который имеет ОГРОМНОЕ количество дочерних элементов.

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

document.getElementById('sortable-lines').style.display="none";

И после того, как документ будет готов, он будет длиться вечно.

http://jsfiddle.net/petersendidit/UZCZc/10/embedded/result/

Для этого открыл ошибку Chrome: http://code.google.com/p/chromium/issues/detail?id=71305

9 голосов
/ 30 января 2011

При скрытии удаление элемента из DOM происходит быстрее, чем при использовании hide().

var sortableLines = $('#sortable-lines');
$('#hide').click(function() {
    $('#timer').text("Hiding");        
    sortableLines.remove();
});

Все еще медленно, когда вы append() возвращаете его в DOM.

Возможный обходной путь - показать первые 10 или около того элементов при нажатии кнопки «Показать», а затем setInterval, чтобы последовательно их отобразить.


Редактировать: Найден еще один хак:

Вы должны установить контейнер на overflow: hidden:

#linecontainer { overflow: hidden; }

При скрытии переместите этот элемент вверх, установив для margin-top большое отрицательное число.

$('#hide').click(function() {
    $('#timer').text("Hiding");
    sortableLines.css('margin-top', '-1000000px');
});

При отображении сбросьте его margin-top.

$('#show').click(function() {
    $('#timer').text("Showing");
    sortableLines.css('margin-top', '0');
});

И он показывает и мгновенно скрывает .

0 голосов
/ 04 августа 2011

Спасибо за ответ выше, он отлично работает и ускоряет процесс.

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

Я полагаю, я знаю, почему это плохо себя ведет.

Когда значение длинного списка элементов установлено на скрытие / показ, скрытые элементы удаляются из потока и помещаются внизу страницы в порядке их удаления.
Это позволяет удалитьэлементы удивительно быстро.

Однако попытка сделать их видимыми снова - это проблема при рендеринге, поскольку chrome должен помнить порядок, в котором эти элементы принадлежали, и, по-видимому, пересчитывать связанные значения.

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

...