Как Я Создал Плагин One Page Scroll С Открытым Исходным Кодом

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

Большинство плагинов, которые я видел, пытаются сделать слишком много, что затрудняет их включение в ваши проекты.

Не так давно Apple представила iPhone 5S. сайт с презентацией , где страница была разделена на разделы, и каждый раздел описывал одну из особенностей продукта.

Я подумал, что это отличный способ представить продукт, не упустив ключевую информацию.

Я пошел искать подходящий плагин и, к своему удивлению, не нашел его.

Так родился плагин прокрутки страниц.



Плагин прокрутки страниц.

Плагин на основе jQuery, позволяющий создать макет страницы с несколькими разделами с использованием минимальной разметки.

Я расскажу вам, как он создавался, от концепции до планирования, тестирования и выпуска бесплатного кода.

Примечание.

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

Поэтому я старался снизить негативный эффект от изменения привычного поведения.

В настройках плагина вы можете установить размеры экрана, при которых плагин возвращается к нормальной прокрутке экрана.

Таким образом, на маломощных устройствах, таких как смартфоны и планшеты, вы сможете поддерживать работоспособность сайта.

Кроме того, вы можете установить продолжительность анимации при переходе между разделами.



Для чего все это?

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

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

1. Чертежи
Я начал планировать плагин от общего к частному.

Он должен прокручиваться по разделам.

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



Как я создал плагин One Page Scroll с открытым исходным кодом

Вы можете представить все в уме, а можете сделать наброски.

Разделите концепцию на небольшие задачи, решая каждую последовательно.

1. Подготовьте расположение разделов.

Давайте отключим обычную прокрутку, применив переполнение: скрыто к телу.

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

2. Настройте триггер ручной прокрутки Мы ловим триггер с помощью jQuery, определяем направление прокрутки и перемещаем макет с помощью CSS. 3. Добавим функции Добавим отзывчивость, цикличность, поддержку прокрутки на сенсорных экранах, нумерацию страниц и т.д. 4. Проверим в разных браузерах.

Мы проверим браузеры Chrome, Safari, Firefox, Internet Explorer 10 и самые популярные операционные системы Windows, Mac OS X, iOS и Android 4.0+.

5. Сделаем плагин доступным в репозитории.

Создадим репозиторий и напишем инструкцию по использованию плагина.

6. Расширим поддержку.

Давайте рассмотрим другие способы увеличения поддержки плагинов.



2. Создание фундамента
После разработки плагина я приступил к созданию основы на этом шаблоне:
  
  
  
  
  
  
  
  
   

!function($) { var defaults = { sectionContainer: "section", … }; $.

fn.onepage_scroll = function(options) { var settings = $.

extend({}, defaults, options); … } }($)

Начинаем шаблон с модуля !function($) {… }($), который помещает глобальную переменную jQuery в локальную область видимости — это поможет снизить нагрузку и предотвратить конфликты с другими библиотеками.

Переменная defaults содержит настройки по умолчанию.

$.

fn.onepage_scroll — основная функция, которая все инициализирует. Если вы делаете свой собственный плагин, не забудьте вместо onepage_scroll написать другое имя.

Вы можете предотвратить стандартную прокрутку, назначив свойство overflow:hidden тегу body. через имя класса, специфичное для плагина.

Важно использовать уникальные имена стилей, чтобы избежать конфликтов с существующими.

Обычно я использую аббревиатуру имени плагина, а затем дефис, отделяемый именем стиля, например: .

onepage-wrapper. Фундамент заложен, переходим к первой функции.



3. Подготовьте макет и расставьте разделы.

Сначала я пошел неправильным путем.

Я думал, что расставлю все разделы по порядку, проходя их по циклу.

Что я получил первым:

var sections = $(settings.sectionContainer); var topPos = 0; $.

each(sections, function(i) { $(this).

css({ position: "absolute", top: topPos + "%" }).

addClass("ops-section").

attr("data-index", i+1); topPos = topPos + 100; });

Цикл перебирает все селекторы (sectionContainer определен в разделе переменных по умолчанию), присваивает позицию: Absolute и присваивает каждому следующему разделу правильную верхнюю позицию, чтобы они не перекрывали друг друга.

Верхняя позиция сохраняется в topPos. Начинаем с нуля и добавляем с каждым циклом.

Чтобы каждый раздел занимал всю страницу, я установил их высоту на 100% и добавил 100 к topPos. Разработка и тестирование заняли у меня пару часов, но на следующем этапе я понял, что во всем этом нет необходимости.



4. Ручной триггер и преобразование страниц.

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

Но есть лучший способ.

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

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

Это также упрощает управление скоростью и другими параметрами анимации.



Как я создал плагин One Page Scroll с открытым исходным кодом

Первое решение не всегда самое эффективное, поэтому не забудьте оставить время для экспериментов.

Теперь осталось только определить направление прокрутки и переместить контейнер в нужном направлении.



function init_scroll(event, delta) { var deltaOfInterest = delta, timeNow = new Date().

getTime(), quietPeriod = 500; // Cancel scroll if currently animating or within quiet period if(timeNow - lastAnimation < quietPeriod + settings.animationTime) { event.preventDefault(); return; } if (deltaOfInterest < 0) { el.moveDown() } else { el.moveUp() } lastAnimation = timeNow; } $(document).

bind('mousewheel DOMMouseScroll', function(event) { event.preventDefault(); var delta = event.originalEvent.wheelDelta || -event.originalEvent.detail; init_scroll(event, delta); });

Сначала мы подключаем функцию к событию колеса мыши (DOMMouseScroll в Firefox), затем можем перехватить данные и определить направление.

Мы интегрируем его в обработку init_scroll, которая за это получает WheelData. В идеальном мире было бы достаточно вычислить изменение в WheelData. Однако при анимации последовательностей необходимо встроить проверку, чтобы событие триггера не дублировалось (иначе при анимации изображение будет перекрываться).

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

Например, в Chrome и Firefox setInterval тормозит в неактивных вкладках, в результате функции не выполняются вовремя.

В результате я остановился на использовании функции, возвращающей текущее время.



var timeNow = new Date().

getTime(), quietPeriod = 500; … if(timeNow - lastAnimation < quietPeriod + settings.animationTime) { event.preventDefault(); return; } … lastAnimation = timeNow;

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

Если он не занят, то трансформация не происходит и анимация не перекрывается.

Надёжнее работать с текущим временем, потому что оно у всех одинаковое.



if (deltaOfInterest < 0) { el.moveDown() } else { el.moveUp() }

Функции moveUp и moveDown изменяют атрибуты макета, чтобы отразить текущее состояние сайта.

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

$.

fn.transformPage = function(settings, pos, index) { … $(this).

css({ "-webkit-transform": ( settings.direction == 'horizontal' ) ? "translate3d(" + pos + "%, 0, 0)" : "translate3d(0, " + pos + "%, 0)", "-webkit-transition": "all " + settings.animationTime + "ms " + settings.easing, "-moz-transform": ( settings.direction == 'horizontal' ) ? "translate3d(" + pos + "%, 0, 0)" : "translate3d(0, " + pos + "%, 0)", "-moz-transition": "all " + settings.animationTime + "ms " + settings.easing, "-ms-transform": ( settings.direction == 'horizontal' ) ? "translate3d(" + pos + "%, 0, 0)" : "translate3d(0, " + pos + "%, 0)", "-ms-transition": "all " + settings.animationTime + "ms " + settings.easing, "transform": ( settings.direction == 'horizontal' ) ? "translate3d(" + pos + "%, 0, 0)" : "translate3d(0, " + pos + "%, 0)", "transition": "all " + settings.animationTime + "ms " + settings.easing }); … }

Это метод трансформации, который сдвигает разделы.

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

Кроме того, процент трансформации еще нужно пересчитывать, поэтому без JavaScript не обойтись.



5. Дополнительные возможности
Сначала я не хотел ничего добавлять, но получил столько отзывов от сообщества GitHub, что решил постепенно улучшать плагин.

Я выпустил версию 1.2.1, в которой добавлено множество обратных вызовов и циклов, а самое сложное — это отзывчивость.

Изначально я не делал плагин с учетом мобильных платформ (о чем сожалею).

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



var defaults = { responsiveFallback: false … }; function responsive() { if ($(window).

width() < settings.responsiveFallback) { $("body").

addClass("disabled-onepage-scroll"); $(document).

unbind('mousewheel DOMMouseScroll'); el.swipeEvents().

unbind("swipeDown swipeUp"); } else { if($("body").

hasClass("disabled-onepage-scroll")) { $("body").

removeClass("disabled-onepage-scroll"); $("html, body, .

wrapper").

animate({ scrollTop: 0 }, "fast"); } el.swipeEvents().

bind("swipeDown", function(event) { if (!$("body").

hasClass("disabled-onepage-scroll")) event.preventDefault(); el.moveUp(); }).

bind("swipeUp", function(event){ if (!$("body").

hasClass("disabled-onepage-scroll")) event.preventDefault(); el.moveDown(); }); $(document).

bind('mousewheel DOMMouseScroll', function(event) { event.preventDefault(); var delta = event.originalEvent.wheelDelta || -event.originalEvent.detail; init_scroll(event, delta); }); } }

Давайте определим переменную по умолчанию.

Мы используем ResponseFallback, чтобы определить, когда плагин должен выполнить откат. Этот код определяет ширину браузера.

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

Если ширина превышает значение, плагин проверяет наличие класса Disabled-onepage-scroll, чтобы убедиться, что он инициализирован.

Если нет, он инициализируется снова.

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



6. Тестирование в разных браузерах.

Тестирование — важная часть разработки; прежде чем выпускать плагин, вам необходимо убедиться, что он работает на большинстве машин.

Я всегда разрабатываю в Chrome — во-первых, мне нравятся его инструменты разработчика, а во-вторых, я знаю, что если плагин работает в Chrome, он, скорее всего, будет работать и в Safari и Opera. Обычно я использую Macbook Air для разработки и имею дома компьютер для тестирования.

После того, как плагин заработает в Chrome, я тестирую его вручную в Safari, Opera и, наконец, в Firefox в Mac OS X, а затем в Chrome, Firefox и Internet Explorer 10 в Windows. Это не все возможные браузеры, но в открытом исходном коде хорошо то, что другие разработчики смогут сами тестировать и исправлять ошибки — в этом его суть.

Не обязательно сразу делать идеальный продукт, но задайте трамплин для старта.

Не забудьте протестировать свои плагины на мобильных устройствах.

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

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



7. Загрузите плагин с открытым исходным кодом.

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

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

Копируем туда плагин и настраиваем структуру.

Структура репозитория Настройте его по своему желанию.

Я делаю это: — каталог демо содержит рабочие демо со всеми необходимыми ресурсами — в корне лежит обычная и сжатая версии плагина — CSS и тестовые ресурсы, такие как изображения (при необходимости), находятся в корне - файл readme в корне Структура ознакомительного файла Важный этап — написание четких инструкций для сообщества open source. Обычно я пишу их в readme, но для сложных случаев может понадобиться вики-страница.

Как я пишу readme: 1. Введение Я объясняю назначение плагина, предоставляю изображение и ссылку на демо.

2. Требования и совместимость.

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

3. Основные принципы использования Пошаговые инструкции: от подключения jQuery к HTML-разметке и вызова функции.

Также описаны настройки.

4. Расширенное использование.

Более сложные инструкции — публичные методы, обратные вызовы и другая полезная информация.

5. Другие ресурсы Ссылки на учебник, спасибо и т. д.

8 Расширение поддержки
В общем, можно было бы обойтись и без jQuery, но я спешил сделать его открытым, поэтому решил сократить время разработки и положиться на готовые функции в jQuery. Но для очистки совести я переработал плагин на чистом JavaScript (также доступна версия с поддержкой Zepto).

На чистом JS нет необходимости включать jQuery, все работает «из коробки».

Чтобы исправить ситуацию и исключительно для читателей Smashing Magazine, я перестроил One Page Scroll, используя чистый JavaScript (также доступна версия Zepto).

В версии на чистом JavaScript вам больше не нужно включать jQuery. Плагин работает прямо из коробки.

Версия на чистом JS и Zepto Репозиторий чистого JavaScript Репозиторий Зепто Переработка плагина на чистом JavaScript Такая обработка может показаться сложной задачей, но это только на первый взгляд. Самое сложное – не ошибиться с математикой.

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

Заодно я реорганизовал структуру скрипта: — значения переменных по умолчанию Все то же самое, что и в предыдущей версии - функция инициализации Подготавливает и организует макет и инициализацию того, что происходит при вызове функции onePageScroll. Здесь находятся все процедуры, которые назначают имена классов, атрибуты и стили позиционирования.

- частные методы Все внутренние методы плагина — события прокрутки, трансформация страниц, адаптивный откат и отслеживание прокрутки.

- публичные методы Все методы для разработчиков: moveDown(), moveUp() и moveTo().

- вспомогательные методы Все, что переопределяет вызовы jQuery. Было пару неприятных моментов — отдельная функция просто для добавления или удаления имени стиля, или использование document.querySelector вместо $.

Но в итоге мы получили более структурированный плагин.

Пересборка плагина для Zepto Я решил поддержать Zepto, несмотря на то, что он предназначен только для самых современных браузеров (IE10+), потому что.

он работает быстрее и эффективнее, чем jQuery 2.0+, имея при этом более гибкий API. Zpeto в 4 раза меньше jQuery, что влияет на скорость загрузки страниц.

Поскольку люди чаще используют смартфоны, Zepto становится лучшей альтернативой.

Плагин из jQuery проще конвертировать в Zepto, поскольку у них схожие API. Почти всё то же самое, кроме анимационной части.

Поскольку функция $.

fn.animate() Zepto поддерживает анимацию CSS3 и обратный вызов анимацииEnd, следующая часть:

$(this).

css({ "-webkit-transform": "translate3d(0, " + pos + "%, 0)", "-webkit-transition": "-webkit-transform " + settings.animationTime + "ms " + settings.easing, "-moz-transform": "translate3d(0, " + pos + "%, 0)", "-moz-transition": "-moz-transform " + settings.animationTime + "ms " + settings.easing, "-ms-transform": "translate3d(0, " + pos + "%, 0)", "-ms-transition": "-ms-transform " + settings.animationTime + "ms " + settings.easing, "transform": "translate3d(0, " + pos + "%, 0)", "transition": "transform " + settings.animationTime + "ms " + settings.easing }); $(this).

one('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend', function(e) { if (typeof settings.afterMove == 'function') settings.afterMove(index, next_el); });

Можно заменить этим кодом:

$(this).

animate({ translate3d: "0, " + pos + "%, 0" }, settings.animationTime, settings.easing, function() { if (typeof settings.afterMove == 'function') settings.afterMove(index, next_el); }); }

Zepto позволяет создавать анимацию без определения всех стилей или самостоятельного назначения обратных вызовов.



И зачем этим заморачиваться?

Чем больше людей используют jQuery, тем сложнее он становится, а иногда и медленнее.

Если вы сделаете поддержку других фреймворков, ваш плагин будет популярнее.

Изменение дизайна с самого начала также поможет вам создавать более качественные плагины в будущем.

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

Без этих потворств чистому JavaScript я лучше понимал, как работает мой плагин – что работает, что влияет на производительность и что можно улучшить.

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

Некоторые плагины могут это сделать.



Заключение.

Ну вот и весь процесс создания плагина One Page Scroll. Были ошибки, но я учился на них по мере развития.

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

Без поддержки таких сообществ, как GitHub, StackOverflow и Smashing Magazine, мне бы не удалось сделать плагин так быстро.

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

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

Ресурсы Демо скачать плагин Теги: #плагин #jQuery #zepto #прокрутка #плагин #разработка сайтов #JavaScript

Вместе с данным постом часто просматривают: