Просмотров: 26674
Дата последнего изменения: 19.08.2021
Сложность урока:
2 уровень - несложные понятия и действия, но не расслабляйтесь.
3
4
5
Недоступно в лицензиях:
Ограничений нет
Пример "моргания": счетчик товаров в корзине пользователя находится в динамической области. Некрасиво прыгает цифра: сначала ноль, потом один. Почему это происходит?
- В файл кеша записывается заглушка "0 товаров в корзине".
- Страница из кеша отдается пользователю и показывается.
- Даже если второй, аяксовый, хит с нужными данными приходит раньше, чем отрендерилась страница, все равно пользователь на мгновение видит заглушку.
- Это происходит из-за того, что все вставки в innerHTML (в том числе из sqlite) происходят на событии DOMContentLoaded.
- Хотя в большинстве случаев виноват даже не DOMContentLoaded, а долгое выполнение аяксового запроса.
Чтобы побороть "моргание", нужно вставить актуальные данные в страницу до того, как она покажется пользователю. Как вставить до рендеринга? есть два варианта:
- document.write - это конструкция останавливает рендеринг страницы, для того, чтобы на лету вставить в DOM новый HTML. Разработчики браузеров не рекомендуют ее использовать, но она работает.
- Разместить Javascript в странице так, чтобы он располагался после HTML'я, к которому обращается. Это старый забытый способ начала 2000-x годов, когда еще jQuery'ая $.ready() не замылила всем глаза. $.ready() или битриксовая BX.ready - это выполнение кода на событии DOMContentLoaded. Это событие гарантирует, что DOM построен и к нему можно безопасно обращаться. Минус этого события в том, что на больших страницах интерфейс уже успевает пользователю показаться, отсюда и моргание.
<!doctype html>
<html>
<body>
<div id="box" style="width: 100px; height: 100px; background: red;"></div>
<script>document.getElementById("box").style.background = "blue";</script>
<table><tr><td>some html below</td></tr></table>
</body>
</html>>
Есть вероятность нарваться на Exception, поэтому можно подстраховаться:
function changeBox()
{
document.getElementById("box").style.background = "blue";
}
var box = document.getElementById("box");
if (box)
{
changeBox();
}
else
{
BX.ready(function() { changeBox(); });
}
Актуальные данные можно получить из:
- Cookies
- SQLite
- LocalStorage
Самый приемлемый вариант - это localStorage. Это key-value хранилище, которое поддерживается всеми браузерами, даже IE8. Данные localStorage доступны мгновенно сразу во всех вкладках. То есть, если у пользователя открыто 10 вкладок магазина и он в одной из них жмет "Добавить в корзину", то через событие localStorage'а можно мгновенно поменять во всех вкладках счетчик корзины.
Для localStorage в Bitrix Framework есть своя обвязка под названием BX.localStorage. Она позволяет указывать время хранения данных. Основные методы:
События:
- BX.addCustomEvent("onLocalStorageSet", function(data) { console.log(data.key, data.value) });
- BX.addCustomEvent("onLocalStorageRemove", function(data) {});
- BX.addCustomEvent("onLocalStorageChange", function(data) {});
В итоге: счетчик корзины и имя пользователя можно кешировать в localStorage и использовать эти данные для борьбы с "морганием".
Что ещё нужно учитывать чтобы избежать "моргания":
- Старайтесь делать верстку так, чтобы вставка динамических областей не приводила к прыганию соседних элементов.
- C помощью метода setAnimation(true) можно добавить эффект плавного появления контента.
- Экспериментируйте с содержимым заглушек. Заглушка может быть пустой, а может повторять содержимое динамической области.