Как я построил одну страницу Scroll Plugin

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

Не так давно, Apple представила iPhone 5S, который сопровождался презентации website 1 , на котором посетители руководствовались вниз разделы страницы и чьи сообщения был сокращен до одного ключевой функции враздел.Я обнаружил, что это отличный способ, чтобы представить продукт, сводя к минимуму риск посетителей случайно прокрутки прошлое ключевую информацию .

Я решил найти плагин, который делает именно это.К моему удивлению, я не нашел простое решение для интеграции в моих текущих проектов.То есть, когда один Page Выделите родился .

Что такое Одна страница Выделите

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

Я объясню, как я построил этот плагин, с самого его начала и до планирования, тестирования и, наконец, положить код там для свободного .

Примечание: Прежде чем создавать этот плагин, я был в курсе споров по поводу “прокрутки угона», когда сайт перегружает родной поведение прокрутки браузера, чтобы создать свой собственный взаимодействие, которое смущает некоторых посетителей.Одна страница Выделите неизбежно идти против этого принципа, так что я решил придумать способы, чтобы облегчить разочарование.Одна хорошая вещь о плагине, что разработчики могут установить запасной вариант, что возвращается прокрутки от его “захвата” государства на его родной поведения для определенных размеров экрана.Таким образом, разработчики могут поддерживать высокую производительность и качество своих веб-сайтов на маломощных устройств, таких как смартфоны и планшеты.Кроме того, вы также можете контролировать длину анимации, которая принимает посетителя из одного раздела в другой, позволяя тем самым избежать медленный переход увидеть на __3 от Apple | iPhone 5S website 2 .

Какова его цель

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

  • Быть простым в использовании,
  • Легко интегрировать
  • Требуют минимального разметку,
  • Сделать одну вещь хорошо (т.е. прокрутки страницы, как веб-сайт iPhone 5S делает) .

1. чертеже Board

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

Visualize either in your mind or in sketches. 3
Визуализация либо в вашем уме или в эскизах.( Просмотр большой version 4 )

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

  1. Подготовка макета и установите разделы .
       Отключить умолчанию прокрутка поведение браузера с CSS, применяя overflow: hidden к body тега.Положение каждой секции в последовательности, при расчете и подключения всех необходимых сведений и классы .
  2. Настройка ручной прокрутки триггер .
       Обнаружить прокрутки триггер с помощью JQuery, а затем определить направление, а затем переместите формат, используя CSS .
  3. Добавить компоненты .
       Добавить реагирования, циклы, поддержка мобильных устройств салфетки, количество страниц и т.д. .
  4. Тест в разных браузерах .
       Убедитесь, что плагин работает отлично во всех современных браузерах (Chrome, Safari, Firefox, Internet Explorer 10) и на самых популярных операционных систем (Windows, Mac OS X, IOS и Android 4.0) .
  5. С открытым исходным кодом плагина .
       Создать новое хранилище, структурирование его и писать инструкции о том, как использовать плагин .
  6. Расширить поддержку .
       Исследуйте другие способы увеличения поддержки плагин .

2. Строительство Foundation

Теперь, я представил себе всю концепцию, я начал строить плагин с этим шаблоном:

!function($) {

   var defaults = {
      sectionContainer: "section",
      …
   };

   $.fn.onepage_scroll = function(options) {
      var settings = $.extend({}, defaults, options);
      …
   }

}($)

Шаблон начинается с !function($) { … }($) модуля, который обеспечивает локальную область видимости в глобальной переменной для JQuery.Цель этой функции заключается в сокращении накладных расходов для поиска JQuery ($) и предотвращения конфликтов с другими библиотеками JavaScript .

defaults переменная в верхней держит параметры по умолчанию для плагина.Так что, если вы не определите любые варианты, он будет Откат к этим значениям .

$.fn.onepage_scroll функция основная функция, которую инициирует все.Не забудьте заменить onepage_scroll с вашим собственным именем функции, если вы создаете свой собственный .

Отключение прокрутки поведение можно легко сделать, добавив overflow: hidden к body тега с помощью CSS через имя класса плагина от конкретных условий.Далее с плагином конкретных именования классов, важно, чтобы избежать конфликтов с существующими CSSстилей.Я обычно иду с сокращенного названия плагина, а затем через дефис, а также описательные слова: например, .onepage-wrapper .

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

3. Подготовить макет и позиция Sections

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

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 определяется в defaults переменной), относится position: absolute и присваивает каждый из них с правильным top позиция, он должен правильно выровнять .

top позиция сохраняется в topPos переменной.Начальное значение составляет 0 и увеличивается, как это перебирает каждого из них.Для того, чтобы каждый раздел целую страницу и правильно складывают все, что я должен был сделать установить высоту каждой секции до 100% и увеличение topPos переменную 100 каждый раз, когда перебирает секции.Теперь, каждый раздел должен сложить правильно, в то время как только первая секция будет доступна для посетителей .

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

4. Руководство курок и Page Transformation

Вы думаете, что следующим шагом будет двигаться каждый раздел ее новому положению, когда прокрутка срабатывает — Я тоже так думал.Как выяснилось, есть лучшее решение.Вместо того чтобы двигаться каждого отдельного раздела каждый раз, когда пользователь прокручивает, что потребует еще один цикл до конца и другой расчет, я обернул все разделы в один контейнер и использовать CSS3 в translate3d, чтобы переместить всю обертку вверх и вниз.Потому что translate3d поддерживает процентные значения на основе, мы можем использовать нашу предыдущую top вычисления позиции, чтобы двигаться каждый раздел в области просмотра без пересчитать его.Еще одно преимущество в том, что это дает вам контроль над сроками и ослабление настройки анимации .

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

The first solution you come up with is not always the most efficient, so make sure to leave time for experimentation. 5
Первое решение вы придумали не всегда самый эффективный, поэтому убедитесь, что оставитьВремя для экспериментов.( Просмотр большой version 6 )

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

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);
});

В приведенном выше фрагменте, во-первых, я связать функцию в mousewheel события (или DOMMouseScroll для Firefox), так что я могу перехватить данные прокрутки, чтобы определить направление прокрутки.При связывании моей init_scroll функция в этих событиях, я могу передать имеющуюся wheelData к init_scroll и определения направления .

В идеальном мире, все, что я должен был бы сделать, чтобы обнаружить и двигаться каждый раздел получить дельту от wheelData переменной, используйте значение, чтобы определить направление и выполнить преобразование.Это, однако, не представляется возможным.Когда вы имеете дело с секвенирования анимации, вы должны создать отказоустойчивый, чтобы предотвратить триггер удвоения, которые могли бы привести анимацию перекрываются.Мы можем использовать setInterval сортировать эту проблему, позвонив каждой анимации индивидуально, с его собственного времени, установленного на части, чтобы создать последовательность.Но для точности и надежности, setInterval дотягивает, потому что каждый браузер обрабатывает его по-разному.Например, в Chrome и Firefox, setInterval дросселируют в неактивных вкладках, в результате чего обратные вызовы не быть обвиненными в времени.В конце концов, я решил обратиться к метку времени .

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

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

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

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

$.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
   });
   …
}

Выше transform метод, который обрабатывает перемещение каждой секции.Как вы можете видеть, я использовал трансформацию CSS3 обрабатывать все манипуляции с помощью JavaScript.Поэтому я сделал это в JavaScript, а не в отдельную таблицу стилей, чтобы позволить разработчикам настроить поведение плагина — в основном времени и ослабления __19 анимации в | за счет собственных вызовов функций, без необходимости ехать на отдельныйстилей и разбираться в настройках.Другая причина заключается в том, что анимация требуетдинамическое значение, чтобы определить процент перехода, который может быть рассчитан только в JavaScript с помощью подсчета количества секций .

5. Дополнительная Features

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

В начале, я не сосредоточиться на создании мобильных первая плагин (который я до сих пор жалею сегодня).Скорее, я использовал простое решение (спасибо Эйке Send 7 за его салфетки событий), чтобы обнаружить и преобразовать данные салфетки в пригодных к использованию данных дельта, для того, чтобы использовать его на моей init_scroll функции,Это не всегда дают лучший результат в мобильных браузерах, таких как пользовательские браузеры Android, так что я в конечном итоге реализации запасной вариант, который позволяет плагин вернуться к своей родной поведения прокрутки, когда браузер достигает определенной ширины.Вот скрипт, который делает что:

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.origi ...

Если вы хотите прочитать полностью статью, посетите сайт наших спонсоров

Comments are closed.