Awebdesign's Blog

Горизонтальная прокрутка с ява-скриптом 2, урок по CSS и jQuery

Перевод Виктории Шидловской урока Horizontal Scrolling Menu made with CSS and jQuery от Andrew Valums.

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

Посмотреть результат

Добаляем базовые стили

div.sc_menu {
/* Установите эти значения, чтобы мы могли просчитать отступ слева*/
position: relative;
height: 145px;
width: 500px;
/* Add scroll-bars */
overflow: auto;
}
ul.sc_menu {
display: block;
height: 110px;
/* Здесь максимальная ширина для пользователей без Javascript */
width: 1500px;
padding: 15px 0 0 15px;
/* Remove default margin */
margin: 0;
background: url(‘navigation.png’);
list-style: none;
}
.sc_menu li {
display: block;
float: left;
padding: 0 4px;
}
.sc_menu a {
display: block;
text-decoration: none;
}
.sc_menu span {
/* Мы добавим заголовок под каждой картинкой */
display: block;
margin-top: 3px;
text-align: center;
font-size: 12px;
color: #fff;
}

Значения “width” и “overflow” добавлены для того, чтобы у тянущегося div-а появились скроллбары. Мы указываем значение “position” для того, чтобы ява-скрипту было легче просчитать отступ. Не забывайте, что отступ всегда просчитывается относительно родителя. Вы можете посмотреть, что получилось, здесь.

Добавляем эффект hover (когда мышь проходит над элементом) и рамки (borders)

Значение “display: none” прячет заголовки, и мы прописываем “display:block” к “:hover”, чтобы показывать их, когда мышка находится над картинкой.

“-webkit-border-radius” и “-moz-border-radius” делают углы наших рамок скругленными в таких браузерах, как Firefox, Safari и Chrome. К сожалению, Internet Explorer не поддерживает это свойство и будет отображать обычные углы.

Вот как выглядит меню, если поддержка ява-скриптов отключена.

Код:

.sc_menu span {
 display: none;
 margin-top: 3px;
 text-align: center;
 font-size: 12px;
 color: #fff;
}
.sc_menu a:hover span {
 display: block;
}
.sc_menu img {
 border: 3px #fff solid;
 -webkit-border-radius: 3px;
 -moz-border-radius: 3px;
}
.sc_menu a:hover img {
 filter:alpha(opacity=50);
 opacity: 0.5;
}

jQuery

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

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js" type="text/javascript"></script>

Вот, что вы должны знать, чтобы понять код:

$() – это сокращенное имя для функции $(document).ready(), самая часто используемая функция jQuery. Это позволяет вызывать скрипт сразу после загрузки дерева страницы.

$(function(){
  // Your code here
});

Мы будем использовать событие “mousemove”, чтобы запускать скрипт при движении мышки над меню.

“ul.width()” не возвращает значение реальной ширины всех изображений, так как мы задали ширину списка с помощью CSS, чтобы выводить все изображения в одну линию. Мы можем получить эту ширину, сложив вместе ширину последнего изображения и его отступ слева.

Мы используем функцию “lastLi[0]” из коллекции jQuery и “offsetLeft”, чтобы получить координаты левого верхнего угла последней картинки относительно div-а.

Атрибут “lastLi[0]” возвращает Х-координату мышки относительно страницы, но нам нужно получать эту координату относительно div-а, поэтому мы воспользуемся “div.offset().left”

Список картинок должен двигаться быстрее, чем мышь над ним, поэтому его движение задаем с помощью формулы “(ulWidth-divWidth) / divWidth”.

Вот ява-скрипт:

$(function(){
 //Вызываем все элементы для более быстрого доступа к ним и указываем ширину     //рабочей области
 var div = $('div.sc_menu'),
               ul = $('ul.sc_menu'),
               // левый отступ (margin) ненумерованного списка
               ulPadding = 15;
  //Указываем переменную для ширины меню
  var divWidth = div.width();
  //Удаляем скроллбары
  div.css({overflow: 'hidden'});
  //Ищем последний элемент списка
  var lastLi = ul.find('li:last-child');
  //Когда пользователь проводит мышкой над меню
  div.mousemove(function(e){
    //Так как ширина списка увеличивается с загрузкой каждой новой картинки,
    //то мы пересчитываем ее каждый раз
    var ulWidth = lastLi[0].offsetLeft + lastLi.outerWidth() + ulPadding;
    var left = (e.pageX - div.offset().left) * (ulWidth-divWidth) / divWidth;
    div.scrollLeft(left);
  });
});

Также решение для нескольких скроллер-меню на одной странице:

$(function(){
//Вызываем все элементы для более быстрого доступа к ним и указываем ширину     //рабочей области

var div = $(’div.sc_menu’),
ul = $(’ul.sc_menu’),
ulPadding = 15;

// Удаляем скроллбары
div.css({overflow: ‘hidden’});

// Когда пользователь проводит мышкой над меню
div.mousemove(function(e){

//Получаем ширину меню
var divWidth = $(this).width();

// Ищем последний элемент списка
var lastLi = $(this).find(’li:last-child’);

//Так как ширина списка увеличивается с загрузкой каждой новой картинки,
//то мы пересчитываем ее каждый раз
var ulWidth = lastLi[0].offsetLeft + lastLi.outerWidth() + ulPadding;
var left = (e.pageX – div.offset().left) * (ulWidth-divWidth) / divWidth;
$(this).scrollLeft(left);
});
});

В общем, нужно перетащить расчеты ширины списка и координат последнего элемента внутрь функции и задействовать $(this).scrollLeft(left) вместо div.scrollLeft(left).

Вот и все! Можете посмотреть финальный результат. Как всегда, не стесняйтесь оставлять комментарии.

Добавила прокрутку с ява-скриптом 3 — горизонтальная прокрутка колесиком и перетаскиванием!

Если хотите понять причины засилия минимализма, массового перехода с флэша на ява-скрипт и jQuery, истерию вокруг HTML5, а также разобраться во Второй Холодной войне между Apple и Microsoft – читайте статью «Почему минимализм, или какой сайт делать»

комментариев 11

Subscribe to comments with RSS.

  1. Demetra said, on 18.11.2011 at 3:17 пп

    Спасибо. Скрипт действительно что надо. Простой, легко вставляется (нужно лишь немного знать CSS). И не нужно делать флэш!

    Нравится

  2. Alena said, on 29.09.2011 at 12:41 пп

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

    Нравится

  3. Максим said, on 20.05.2011 at 11:06 пп

    Спасибо автора за отличную статью!

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

    Буду очень благодарен!

    Нравится

    • awebdesign said, on 21.05.2011 at 12:44 пп

      Легче просто найти другой движок с нужным функционалом, заодно набраться идей, так как очень много чего теперь на эту тему и с отличным решением. Например, похожее решение здесь http://sorgalla.com/projects/jcarousel/examples/static_simple.html
      Его тютор здесь: http://sorgalla.com/projects/jcarousel/ под названием Simple carousel.
      Думаю, если к нему прикрепить еще реакцию на mouse hover, то получится как раз то, что надо.
      А вообще, открываете любой сайт с понравившимся функционалом, открываете исходный код в Мозилле и тыкаете на все ссылки в хэдере на jQuery и css (в IE так не получится), копируете код, собираете на локалке то же самое со своими links — и вуаля! JQuery является свободно распространяемой библиотекой, так что, думаю, муки совести не должны беспокоить за сдиралово. Дополнительно можно успокоить себя тем, что код все равно пишут не создатели сайта, а люди, которые конкретно разрабатывают решения с помощью jQuery.

      Нравится

      • Максим said, on 21.05.2011 at 9:33 пп

        Спасибо за подсказку. Буду пробовать

        Нравится

  4. мария said, on 16.05.2010 at 2:07 пп

    и еще один небольшой вопрос — можно ли как-то контролировать скорость прокрутки при движении мышки справа налево особенно (происходит резкий скачок)
    в общем поставить фиксированное ограничение на скорость перемотки.
    буду очень благодарна за подсказку.

    Нравится

    • awebdesign said, on 16.05.2010 at 3:09 пп

      Попробуйте поиграть со значением (ulWidth-divWidth) / divWidth, возьмите в дополнительные скобки и попробуйте добавлять или отнимать значения, не уверена, но должно сработать, раз уж этот кусок кода определяет скорость движения меню. Более радикально — умножить или разделить на какое-то значение, вроде как здесь:

      var left = (e.pageX — div.offset().left) *( (ulWidth-divWidth) / (divWidth / 2));

      Нравится

  5. мария said, on 16.05.2010 at 11:33 дп

    спасибо за замечательный скрипт!!

    а как изменить высоту полосы прокрутки под картинками? замучилась — при высоте картинки 600 пикс, полоса прокрутки под ней занимет примерно 250-300 пикселей, некрасиво)

    Нравится

  6. Иван Павлюченко said, on 04.05.2010 at 11:42 пп

    Большое спасибо за информацию, буду использовать.🙂

    Нравится

  7. Роберт said, on 29.04.2010 at 11:53 дп

    Жесть! Нет ну правда, просто слов нету!🙂

    Нравится


Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s

%d такие блоггеры, как: