Статьи

Слайдер-эффект jQuery Coda

Хотя Panic на самом деле не изобрел эффект, скользящие панели на Coda — отличная реализация этого эффекта. В этой статье мы разберем части, необходимые для создания эффекта, и способы его улучшения.

Как решить проблему

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

  1. Отлично ухудшается без JavaScript
  2. Эффект раздвижных панелей без зависания процессора браузера
  3. Кнопки «Следующая» и «Предыдущая» добавлены с использованием JavaScript, поскольку они не используются без JavaScript
  4. Попадание на страницу с определенным хешем (т.е. page.html # preview) показывает правую вкладку и выделяет правильную навигацию
  5. Любая ссылка на странице, которая ссылается на панель, должна вызывать эффект и выделять правильную навигацию — это должно происходить без дополнительной работы.

Хеш является выделенной частью (включая символ #) в: http://jqueryfordesigners.com/page.html #example

На самом деле, наша версия этого слайдера будет лучше, чем Panic и текущие плагины jQuery, если мы сможем удовлетворить все требования. Например, в примере «Паника», ссылка на панель предварительного просмотра неправильно подсвечивает навигацию. Все это решение в значительной степени будет зависеть от плагина scrollTo Ариэля Флезлера и, в частности, от его «адаптеров» для повышения мощности плагина scrollTo.

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

Посмотрите скринкаст с эффектом слайдера Coda ( альтернативная версия Flash ): посмотрите демо и исходный код, используемый в скринкасте
. 90Mb, флэш-версия потоковая — я также заметил, что звук немного левее — я исправлю это в следующий раз!)

Требуются плагины

Наряду с jQuery нам понадобятся следующие плагины — я рекомендую использовать минимизированные версии для производства и, возможно, даже для разработки (ссылки для загрузки можно найти внизу связанных страниц):

наценка

Требование 1: ухудшается без включения JavaScript

Чтобы убедиться, что это работает без JavaScript, мы будем использовать свойство переполнения CSS для управления эффектом. Таким образом, наши панели будут по-прежнему фокусироваться, чтобы увидеть, нажимает ли пользователь или URL ссылается на конкретную панель.

HTML

Стоит отметить, что хотя мы могли бы прокручивать отдельные панели внутри одного вложенного DIV, чтобы JavaScript работал, это будет вложенный DIV, а не отдельные панели. Вы можете увидеть это в разметке ниже:

<div id="slider">
<ul class="navigation">
<li><a href="#sites">Sites</a></li>
<li><a href="#files">Files</a></li>
<li><a href="#editor">Editor</a></li>
<li><a href="#preview">Preview</a></li>
<li><a href="#css">CSS</a></li>
<li><a href="#terminal">Terminal</a></li>
<li><a href="#books">Books</a></li>
</ul>

<!-- element with overflow applied -->
<div class="scroll">
<!-- the element that will be scrolled during the effect -->
<div class="scrollContainer">
<!-- our individual panels -->
<div class="panel" id="sites"> ... </div>
<div class="panel" id="files"> ... </div>
<div class="panel" id="editor"> ... </div>
<div class="panel" id="preview"> ... </div>
<div class="panel" id="css"> ... </div>
<div class="panel" id="terminal"> ... </div>
<div class="panel" id="books"> ... </div>
</div>
</div>
</div>

Вот и все. Без CSS эта разметка отлично работает для нашего контента, почти так же, как вкладки работают без JavaScript и CSS.

CSS

Я не буду подробно описывать все CSS, такие как эффекты навигации или затенения — только CSS, необходимый для правильного создания эффекта.

#slider {
width: 620px;
margin: 0 auto;
position: relative;
}

.scroll {
height: 250px;
overflow: auto;
position: relative; /* fix for IE to respect overflow */
clear: left;
background: #FFFFFF url(images/content_pane-gradient.gif) repeat-x scroll left bottom;
}

.scrollContainer div.panel {
padding: 20px;
height: 210px;
width: 580px; /* change to 560px if not using JS to remove rh.scroll */
}

Следует также отметить , что я выбираю использовать — таким образом, если пользователь действительно имеет JavaScript отключен, будет визуальный дие , что панели можно прокручивать. Если вы хотите удалить горизонтальную прокрутку в IE, я бы порекомендовал изменить ширину на 560 пикселей, чтобы учесть правую полосу прокрутки.overflow: auto;.scrollContainer div.panel

Я также планирую включить кнопки прокрутки, чтобы идти влево и вправо. Хотя элементы будут создаваться с помощью JavaScript, нам все еще нужен CSS, чтобы расположить кнопки в нужном месте. Наш JavaScript будет помещать кнопки до и после внешнего элемента. Мы должны использовать абсолютное позиционирование , чтобы разместить их, так это то , почему было применено:div.scroll#sliderposition: relative;

.scrollButtons {
position: absolute;
top: 150px;
cursor: pointer;
}

.scrollButtons.left {
left: -20px;
}

.scrollButtons.right {
right: -20px;
}

JQuery

Требование 2: эффект раздвижных панелей без перегрузки процессора браузера

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

Обязательные плагины

<script src="jquery-1.2.6.min.js" type="text/javascript"></script>
<script src="jquery.scrollTo-1.3.3-min.js" type="text/javascript"></script>
<script src="jquery.localscroll-1.2.5-min.js" type="text/javascript"></script>
<script src="jquery.serialScroll-1.2.1-min.js" type="text/javascript"></script>

Следующая и предыдущая кнопки

Требование 3: добавлены кнопки «назад» и «вперед»

Это простой ванильный jQuery, вот фрагмент из окончательного кода:

var $scroll = $('#slider .scroll');

$scroll
.before('<img class="scrollButtons left" src="images/scroll_left.png" />')
.after('<img class="scrollButtons right" src="images/scroll_right.png" />');

Обратите внимание на классы, которые я применил scrollButtonsк изображениям, чтобы они были расположены правильно.

Обновления навигации автоматически

Требование 4: попадание на страницу с определенным хешем выделяет правильную навигацию

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

Например, если элемент показан, идентификатор ‘sites’ отправляется нашему триггеру. Наша функция запуска будет выглядеть ссылки в навигации, заканчивающийся «#sites»: . Эта триггерная функция будет прикреплена к свойству в параметрах прокрутки и вызывается при первой загрузке страницы с хешем в URL.div#sites<a href="#sites">Sites</a>onAfter

// bind the navigation clicks to update the selected nav:
$('#slider .navigation').find('a').click(selectNav);

// handle nav selection - lots of nice chaining 🙂
function selectNav() {
$(this)
.parents('ul:first') // find the first UL parent
.find('a') // find all the A elements
.removeClass('selected') // remove from all
.end() // go back to all A elements
.end() // go back to 'this' element
.addClass('selected');
}

function trigger(data) {
// within the .navigation element, find the A element
// whose href ends with ID ($= is ends with)
var el = $('#slider .navigation').find('a[href$="' + data.id + '"]').get(0);

// we're passing the actual element, and not the jQuery instance.
selectNav.call(el);
}

Мне пришлось отделить selectNavфункцию, потому что она также вызывается, когда пользователь нажимает на навигационные ссылки. Чтобы выполнить это требование, после загрузки страницы нам нужно проверить, есть ли хэш в URL, и если это так, вызвать функцию ‘scrollerComplete’:

if (window.location.hash) {
trigger({ id : window.location.hash.substr(1)});
} else {
$('#slider .navigation a:first').click();
}

По умолчанию мы запускаем клик по первому элементу навигации, если в URL нет хэша.

Любой эффект запуска ссылки

Требование 5. Любая ссылка на странице, которая ссылается на панель, должна вызывать эффект

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

Код JQuery

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

// when the DOM is ready...
$(document).ready(function () {

var $panels = $('#slider .scrollContainer > div');
var $container = $('#slider .scrollContainer');

// if false, we'll float all the panels left and fix the width
// of the container
var horizontal = true;

// float the panels left if we're going horizontal
if (horizontal) {
$panels.css({
'float' : 'left',
'position' : 'relative' // IE fix to ensure overflow is hidden
});

// calculate a new width for the container (so it holds all panels)
$container.css('width', $panels[0].offsetWidth * $panels.length);
}

// collect the scroll object, at the same time apply the hidden overflow
// to remove the default scrollbars that will appear
var $scroll = $('#slider .scroll').css('overflow', 'hidden');

// apply our left + right buttons
$scroll
.before('<img class="scrollButtons left" src="images/scroll_left.png" />')
.after('<img class="scrollButtons right" src="images/scroll_right.png" />');

// handle nav selection
function selectNav() {
$(this)
.parents('ul:first')
.find('a')
.removeClass('selected')
.end()
.end()
.addClass('selected');
}

$('#slider .navigation').find('a').click(selectNav);

// go find the navigation link that has this target and select the nav
function trigger(data) {
var el = $('#slider .navigation').find('a[href$="' + data.id + '"]').get(0);
selectNav.call(el);
}

if (window.location.hash) {
trigger({ id : window.location.hash.substr(1) });
} else {
$('ul.navigation a:first').click();
}

// offset is used to move to *exactly* the right place, since I'm using
// padding on my example, I need to subtract the amount of padding to
// the offset. Try removing this to get a good idea of the effect
var offset = parseInt((horizontal ?
$container.css('paddingTop') :
$container.css('paddingLeft'))
|| 0) * -1;


var scrollOptions = {
target: $scroll, // the element that has the overflow

// can be a selector which will be relative to the target
items: $panels,

navigation: '.navigation a',

// selectors are NOT relative to document, i.e. make sure they're unique
prev: 'img.left',
next: 'img.right',

// allow the scroll effect to run both directions
axis: 'xy',

onAfter: trigger, // our final callback

offset: offset,

// duration of the sliding effect
duration: 500,

// easing - can be used with the easing plugin:
// http://gsgd.co.uk/sandbox/jquery/easing/
easing: 'swing'
};

// apply serialScroll to the slider - we chose this plugin because it
// supports// the indexed next and previous scroll along with hooking
// in to our navigation.
$('#slider').serialScroll(scrollOptions);

// now apply localScroll to hook any other arbitrary links to trigger
// the effect
$.localScroll(scrollOptions);

// finally, if the URL has a hash, move the slider in to position,
// setting the duration to 1 because I don't want it to scroll in the
// very first page load. We don't always need this, but it ensures
// the positioning is absolutely spot on when the pages loads.
scrollOptions.duration = 1;
$.localScroll.hash(scrollOptions);

});

Заворачивать

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