Пишем скроллинг на весь экран с Vue.js

Programming Vue.js Fullpage Scroll

 

Перевод статьи на webdeasy.de

При таком скроллинге на весь экран нормальная прокрутка отключается, и вы всегда переходите точно на следующую секцию. Ниже, с помощью Vue.js, вы самостоятельно напишите код для подобной прокрутки.

 

Оглавление

 

Демо

Фреймворки для прокрутки на всю страницу (Fullpage Scroll)

Структура HTML

CSS

Vue.js (JavaScript)

Заключение

 

Демо

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

Однако в браузере Microsoft Edge (преемнике IE) есть небольшая проблема: чистая плавная прокрутка (Smooth Scroll) здесь не поддерживается. Прокрутка немного прерывистая, но все функции по-прежнему можно использовать. Поэтому мы нашли альтернативное решение.

 

Если вы все еще в поиске дизайнерского вдохновления, у меня есть еще одна страница, на которой, на мой взгляд, очень хорошо настроен скроллинг:

Strategies

Фреймворки для прокрутки на всю страницу (Fullpage Scroll)

Я знаю, что существует уже несколько действительно хороших фреймворков для прокрутки в Vue.js, например такой как здесь. Однако гораздо круче написать код самостоятельно. Тем более у вас будет меньше «ненужных» функций на сайте, которые вы не используете.

Если вы не дружите с Vue.js, вы можете использовать то же самое в React , AngularJS или jQuery . Процедура в основном похожа. Некоторые функции, конечно, придется адаптировать к фреймворку.

Структура HTML

Для начала нам нужен контейнер, в котором будет работать наше Vue.js приложение. Поэтому создадим контейнер #app . Внутри будет вся остальная разметка HTML.

Теперь создадим наши секции. Внутри каждой секции мы можем разместить и стилизовать любой наш контент.

Следующим шагом создадим боковое меню. Которое позволяет перейти к другой секции, после щелчка на которой и отобразится наша секция.

Объясню код выше: для создания меню мы создали обертку (wrapper) .sections-menu . В нем есть тег span, который содержит некоторые директивы для Vue.js. Ниже описаны данные директивы:

  Атрибуты     Значения     Описание  

 

  v-bind:class  

 

{active: activeSection == index}   Тег возвращает класс в active, если текущая итерация цикла равна активной секции.  

 

  v-on:click  

 

scrollToSection (index)   Нажатие на ссылку вызывает функцию scrollToSection(). В качестве параметра передается ID секции.  

 

  v-for  

 

(offset, index) in offset   Число элементов меню равно количеству элементов в массиве offset. Значения index равны идентификаторам секций.  

 

  v-bind:key  

 

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

CSS

Чтобы эффект полной прокрутки экрана был как таковым, каждая секция должна быть не менее 100vh (то есть в высоту экрана). Таким образом, вы должны следить, чтобы контент в секции был ориентирован на эту высоту.

В нашем примере у нас есть только заголовок и подзаголовок. Для наглядности взгляните на демо выше.

Навигация

Я оформил навигационное меню как можно проще. Белые точки, где активная точка жирнее и крупнее. Кроме того, меню всегда находится на правой стороне экрана. CSS выглядит так:

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

Vue.js (JavaScript)

JavaScript здесь оказался самой сложной частью. Потому что нам нужно охватить все современные браузеры, а также мобильные устройства.

Инициализация Vue.js приложения

Сперва инициализируем приложение Vue.js. Мы уже создали контейнер #app в HTML.

Объявление и инициализация переменных

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

Рассчитываем смещения

Теперь нам нужно вычислить смещения (верхний край секций) отдельных секций. Преимущество заключается в том, что нам не нужно пересчитывать смещение каждый раз при прокрутке.

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

Функция calculateSectionOffsets() вызывается один раз при создании приложения, в функции created() .

Слушатель событий (Event Listener)

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

Также в функции destroy() удаляем слушатели событий при выходе из приложения.

Как видно из комментариев, для разных браузеров существуют разные события. Для некоторых браузеров задан параметр passive: false . Этот параметр должен быть обязательным, иначе прокрутка не будет плавной, а также будут выводиться ошибки в консоли.

Функция прокрутки

Данная функция вызывается нашими HTML-ссылками. По которым мы и переходим к секциям. Идентификатор id это идентификатор секции. Значение inMove обеспечивает нам небольшую задержку. Это значит, что мы можем прокручивать только каждые 400 мс (0,4 с). Если параметр force установить в true то задержку мы пропустим.

Распознавание направления прокрутки

Функция handleMouseWheel является слушателем события прокрутки на десктопах (события mousewheel DOMMouseScroll ).

Через значение wheelDelta события мы можем определить, прокручивает пользователь вверх или вниз. Соответственно, следующим шагом мы выполняем функцииmoveUp() или moveDown(). В конце e.preventDefault() и return false; завершают событие.

Прокручивание секции вверх и вниз

Следующие две функции при вызове один раз выполнят прокрутку вверх или вниз. Если мы прокручиваем вниз, а номер секции меньше 0, мы переходим к последней секции. И наоборот, если новая секция больше, чем количество секций, мы переходим к первой секции. 0 это первая секция.

В функциях мы написали бесконечный скроллинг. Если это не написать, то мы просто не сможем выполнить Swipe в крайних секциях, только если в обратном направлении.

Определение мобильных свайпов

Для этого у нас есть события движения touchstart и touchmove , через которые мы можем контролировать прокрутку пользователя. Когда пользователь начинает прокручивать происходит вызов события touchStart(). В ней мы сохраняем значение позиции Y. Когда пользователь затем перемещает палец по дисплею вызывается событие touchMove().

Затем мы сравниваем эти два значения и видим, прокручивает ли пользователь вверх или вниз. Соответственно, вызываются функции moveUp() или moveDown(), которые мы создали ранее.

Заключение

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

Полный код вы найдете в моем pen на Codepen.

Если у вас есть предложения по улучшению или правке кода, пожалуйста, не стесняйтесь писать их в комментариях! 🙂