Эффект слайдов на сайте — через грабли на собственном велосипеде

в 14:39, , рубрики: Google Chrome, html, javascript, parallax, скроллинг, метки: , ,

Работая над одним из сайтов столкнулись с необходимостью реализовать эффект слайдов.
А именно — при вертикальном скроллинге страницы она должна перемещаться не как единое целое, а как складываемая пачка отдельных листов.
Не хотелось бы утруждать никого программным кодом (при необходимости в следующей статье), поэтому расскажу какое решение мы использовали и как к нему шли, используя вкрапления псевдокода только для уточнения некоторых моментов.

Первая мысль была использовать библиотеку для добавления parallax эффекта на страницу, коих уже достаточно много можно найти в интернете. Однако нам не нужно было мощное универсальное решение, и время затраченное на обзор, выбор и настройку стороннего решения наверняка превысило бы решение задачи в лоб своими силами. Да и жажда собрать собственные шишки и узнать основы окончательно перевесила чашу весов в пользу собственного велосипеда.

Разработку мы традиционно ведем в Firefox+firebug.

Задача по сути сводилась к изменению координат блоков сайта при скроллинге документа внутри окна браузера.

С помощью jQuery просто привязываемся к событию onscroll документа и прописываем там изменение положения блоков в зависимости от положения документа внутри окна.

Грабли №1: Если в процессе скроллинга произвести манипуляции с DOM, влияющие на высоту всего документа, то мы получим тормоза из-за перестройки и перерисовки контента, а самое неприятное, так это скачки при скроллинге из-за изменения размеров области прокрутки и реинициализации скроллбара.

Чтобы избежать этого мы приняли решение не двигать элементы находящиеся на первом уровне иерархии документа.

Каждый слайд в итоге стал представлять собой неизменный по размерам и положению на странице div (.parent), внутри которого располагается блок-обертка (.wrapper), который и содержит контент слайда.
При скроллинге документа для каждого слайда анализируется положение его .parent блока по отношению к окну браузера (значение X = jQuery(.parent).offset().top — jQuery(window).scrollTop(); ).
При отрицательном значении X делаем смещение .wrapper ( position: relative; top: X;)

Казалось бы проблема решена, однако Грабли №2 — прогон этого решения в Chrome дает неприятные ощущения. Слайды, которые должны просто задерживаться у верха окна, начинают неприятно подергиваться.

Дело в том, что в отличие от Firefox Chrome при скроллинге страницы сначала отрисовывает ее новое положение, а затем вызывает onScroll, где мы меняем координаты блока и страница отрисовывается повторно.

Исправить ситуацию позволило задание нужным элентам .wrapper фиксированного позиционирования (position: fixed;). Такие элементы не меняют своего экранного положения при скроллинге. Осталось только рассчитать смещение .wrapper относительно окна, а не родительского элемента и рывки исчезают.

Грабли №3: в некоторых мобильных браузерах событие onScroll не генерируется до полной остановки скроллинга, что приводит к чудовищным задержкам “анимации”.
Решением может стать вызов пересчета координат по таймеру, а еще лучше через requestAnimationFrame.

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

Автор: TemaAE

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js