Как заставить GIF вращаться при загрузке дерева в Javascript

У меня есть дерево, которое заполняется через веб-службу - эта часть очень быстрая, часть, которая немного медленнее, заполняет дерево... У меня есть вращающееся изображение gif, которое вращается во время загрузки службы. Поскольку я использую триггер ajaxStop и ajaxStart, gif перестает вращаться после завершения запроса ajax, что правильно. Однако, поскольку загрузка занимает долю секунды, картинка зависает на эту долю секунды, что выглядит непрофессионально.

Как заставить gif вращаться, пока дерево не загрузится?


person sarsnake    schedule 16.02.2010    source источник


Ответы (3)


Браузеры отдают низкий приоритет обновлению изображения, поэтому пока ваш код манипулирует/вставляет в DOM, браузер занят этим и не успевает перерисовывать изображение.

Вы мало что можете сделать, кроме как оптимизировать свой код, чтобы обработка данных ajax была менее интенсивной, или, например, если вы получаете список из 1000 элементов, вставляйте их на страницу с интервалами. из 50, с небольшой задержкой между каждым, поэтому браузер успевает перерисовать.

YMMV, может, в Хроме выглядит отлично, а в IE зависает на 5 секунд.

person adamJLev    schedule 16.02.2010
comment
Мне повезло с установкой порога, скажем, 60-100 мс, и приостановкой модификации DOM после его превышения (возобновление после такой же короткой задержки для обновлений пользовательского интерфейса). Это не относится к браузерам, которые откладывают длительные вычисления до завершения сценария, поэтому стоит оставить порог немного ниже, чем это абсолютно необходимо, особенно если модификации вызывают значительные изменения макета. - person Shog9; 16.02.2010
comment
Я вернулся к замене GIF текстом - person sarsnake; 17.02.2010

Браузеры обычно не обновляют изображения во время выполнения кода JavaScript. Если вам нужно, чтобы счетчик продолжал анимацию во время заполнения DOM, ваша функция заполнения должна будет передавать управление обратно браузеру несколько раз в секунду, чтобы позволить ему обновить изображение, как правило, путем установки тайм-аута (без задержки или очень короткого delay), который вызывает процесс заполнения, а затем возвращается.

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

IMO, вероятно, было бы лучше остановить счетчик и затем обновить DOM. Вы все равно получите паузу, но без остановки счетчика это будет не так заметно. Чтобы дать браузеру возможность обновить счетчик после того, как ajaxStop изменил свой src, используйте нулевой тайм-аут-продолжение в своей функции обратного вызова AJAX, чтобы по завершении браузер получил возможность отобразить измененный счетчик, прежде чем перейти к длительному код населения.

Ускорение этого шага населения определенно стоит, хотя это немного другая тема. (Добавление большого количества элементов DOM один за другим по своей сути является медленным, поскольку каждая операция должна тратить больше времени на выполнение операций со списками. Одновременное добавление множества элементов DOM с помощью DocumentFragment выполняется быстро, но включение всех этих элементов DOM во фрагмент в во-первых, может быть не так. Парсинг всего innerHTML сразу, как правило, быстрый, но генерация HTML без дыр в безопасности внедрения вызывает раздражение; сериализация и повторный анализ через innerHTML+= медленнее и совершенно ужасно. IE/HTML5 insertAdjacentHTML быстр, но требует резервная реализация для многих браузеров: идеально быстрое манипулирование диапазоном, возврат к медленным вызовам DOM от узла к узлу для браузеров без диапазона. DOM, потому что это именно то, что он делает.)

person bobince    schedule 16.02.2010
comment
Я использую плагин dynatree jquery - по сути, я рекурсивно заполняю дерево результатами веб-службы JSON. Я уже оптимизировал заселение узлов с 1,5 минут до полсекунды. - person sarsnake; 16.02.2010

Хотя манипулирование DOM на лету действительно утомительно для многих браузеров (особенно старых), вы можете захотеть максимально оптимизировать то, что вы там делаете.

Кроме того, еще одной хорошей идеей было бы убедиться, что вы используете jQuery 1.4, который намного быстрее для выполнения таких операций.

Вы можете увидеть полезный тест (1.3 против 1.4), выполненный командой jQuery, который иллюстрирует это здесь:

http://jquery14.com/day-01/jquery-14

person matdumsa    schedule 16.02.2010
comment
Я подумываю об обновлении, но я между крайними сроками, поэтому я бы предпочел не сейчас. Что-то, что нужно иметь в виду для следующей версии в любом случае. - person sarsnake; 16.02.2010