Pull to refresh

Анимированные меню на jQuery

Reading time 6 min
Views 5.3K
Original author: Homar
Недавно я наткнулся на сайт Dragon Interactive (dragoninteractive.com). Сайт этот достаточно добротно сделан в плане дизайна. А изюминкой можно назвать их анимированное меню. Ну вот если бы это было сделано в Adobe Flash, я даже и не упоминал бы о таком. Но при более близком рассмотрении оказалось, что их меню — это сочетание простых XHTML, CSS и Javascript. В данной статье я собираюсь продемонстрировать, как создавать менюшки (очень близкие к Dragon Interactive’s menu).

Смотрим демо

Скачать PSD

Проектируем спрайт


Чтобы начать, вам необходимо создать спрайт со своим дизайном в Adobe Photoshop или в другом графическом редакторе. Я тоже по-быстрому создал повторяющийся симпатичный фон для кнопок:


XHTML разметка


Вот XHTML разметка, которая использована в демке:

<ul id="menu">
  <li><a href="#" class="home"><span></span></a></li>
  <li><a href="#" class="portfolio"><span></span></a></li>
</ul>


* This source code was highlighted with Source Code Highlighter.


Как вы могли убедиться, для структуры меню используется неупорядоченный список. В данной заметке я собираюсь создать только 2 пункта меню. Вы можете добавить, сколько пожелаете. Обратите внимание, что каждому пункту назначен отдельный свой собственный класс. Это деление нам понадобится при оформлении CSS.

CSS


Для демо я назначил повторяющееся изображение в качестве фона для <ul> элемента. Также назначил высоту и ширину:
ul#menu {
width:80%;
height:102px;
background:url(bg.png) repeat-x;
list-style:none;
margin:0;
padding:0;
padding-top:20px;
padding-left:20%;
}

Теперь используем свойство float, чтобы выровнять элементы <li> по горизонтали:
ul#menu li {
float:left;
}

Ну вот и добрались до самого интересного! Нам нужно добавить спрайт в качестве фонового изображения для каждого пункта меню. Так как нам нужно отображать только определенную часть спрайта для каждого меню, мы ограничиваем рисунок по высоте и ширине, а нужную часть получаем сдвигом изображения. Давайте посмотрим на следующий спрайт:
image
Каждая колонка представляет отдельный пункт меню. В нашем случае 2 колонки, так как мы делаем только 2 пункта меню. Нижний ряд представляет собой внешний вид меню, когда на него будет наведен курсор мышки.
Теперь мы задаем высоту кнопки меню 81px и ширину 159px. Если выровнять изображение в верхний левый угол, то мы увидим только кнопку «Home»:
image
Все потому, что кнопка «Home» была нарисована именно с такими высотой и шириной. Так как фоновое изображение позиционировано в левый верхний угол — это будет единственное, что поместится внутри пункта меню — чего мы собственно и добивались.

Как мы опишем это в CSS? Для начала нужно понять, что во многих случаях нам понадобится больше, чем только 1 пункт меню (в нашем случае — 2 кнопки). Следовательно, было бы проще, если мы написали некий общий CSS для всех кнопок (например, CSS, который будет унаследован каждым пунктом меню). Мы также сможем добавлять (или изменять) эти общие атрибуты CSS путем написания отдельных указаний для отдельных классов по каждой отдельной кнопке (см. XHTML разметку). Вот такой общий CSS используется в демо:
ul#menu li a {
background:url(sprite.png) no-repeat scroll top left;
display:block;
height:81px;
position:relative;
}

В данном коде мы выровняли фоновое изображение по левому верхнему углу. Для кнопки «Home» будет все отлично. Но вот для кнопки «Portfolio» нам потребуется переписать атрибут позиционирования изображения, используя отдельный класс (см. XHTML разметку).
Также стоит обратить внимание, что мы задали здесь высоту, так как все кнопки имеют одинаковую высоту. Так как кнопки по умолчанию отображаются с свойством inline, мы должны использовать «display:block», чтобы использовалась указанная высота. И в конце мы должны указать относительное позиционирование. Позже станет ясно, зачем нам это.
Теперь нам нужно написать CSS для каждой отдельной кнопки. Для этого мы используем отдельные классы для кнопок (см. разметку). В нашем примере всего 2 кнопки. Кнопке «Home» назначен класс «home». Кнопке «Portfolio» — «portfolio». Таким образом, стало возможно назначить отдельные CSS-свойства для каждой кнопки:
ul#menu li a.home {
width:159px;
}

ul#menu li a.portfolio {
width:157px;
background-position:-159px 0px;
}

Вот здесь мы задаем ширину каждой кнопки, так как каждая из них может иметь свою ширину в зависимости от дизайна. Также здесь мы переписываем атрибут background-position, если это необходимо. Для кнопки «Home» этого делать не нужно, так как нужное значение задано в общих CSS свойствах («top left»).

Для кнопки «Portfolio» нам необходимо задать новые координаты внутри спрайта. Так как кнопка «Home» имеет ширину 159px, нам потребуется сдвинуть фоновое изображение на 159px влево, чтобы отобразилась область для «Portfolio». Достигается это путем установки “background-position:-159px 0px;”. Мы говорим браузеру, что нам нужно сместить фоновое изобрадение на 159 пикселей влево и на 0 пикселей вниз.
image
Теперь нам осталось задать поведение при наведении мышки (состояние «hover»). Анимация должна сделать плавный переход между 2 состояниями кнопки. Для задания состояния «hover» мы будем использовать тег <span>. Далее мы используем CSS таким образом, чтобы span тег полностью занял всю кнопку (стал абсолютно такого же размера). Нам потребуется сдвинуть изображение вниз для тега span, чтобы отобразить «hover» область спрайта. Как и прежде, будем использовать общий CSS:
ul#menu li a span {
background:url(sprite.png) no-repeat scroll bottom left;
display:block;
position:absolute;
top:0;
left:0;
height:100%;
width:100%;
z-index:100;
}

Обратите внимание, что здесь мы опять используем «display:block», так как по умолчанию тег <span> отображается как inline. Теперь, когда он отображается как block, мы можем задать высоту и ширину в значение 100% — чтобы полностью заполнить кнопку и сделать их одного размера. Также обратите внимание, что мы назначаем тегу span «position:absolute», чтобы можно было задать z-index. Задавая более высокий z-index мы гарантированно получим фоновое изображение тега span поверх фонового изображения кнопки. Все, что осталось теперь сделать, это выровнять фоновое изображение для тега <span>:
ul#menu li a.home span {
background-position:0px -81px;
}
ul#menu li a.portfolio span {
background-position:-159px -81px;
}

Мы смещаем фоновое изображение каждого span тега на 81 пиксель вниз (так как высота кнопки «Home» 81px). Это позволит отобразить состояние «hover» посредством span тега. Как и раньше, мы также сместим фон влево на 159px для кнопки «Portfolio».

Используем jQuery для анимации


Анимацию достичь здесь будет крайне просто. Мы будем использовать jQuery, чтобы анимированно изменить прозрачность тега span. Помним, что тег span характеризует состояние «hover». Следовательно, состояние когда виден span, должно отображаться в момент наведения мышки. Таким образом, нам нужно спрятать это состояние в момент загрузки страницы. Для этого мы установим прозрачность тега span в «0»:
$(function() {
// set opacity to nill on page load
$("ul#menu span").css("opacity","0");
// the rest of the code will go here
});


* This source code was highlighted with Source Code Highlighter.

Размещая код внутри "$(function() { … });" мы говорим браузеру выполнить код только когда страница загрузилась.
Чтобы добавить анимацию, мы используем следующий код:
// on mouse over
$("ul#menu span").hover(function () {
// animate opacity to full
$(this).stop().animate({
opacity: 1
}, 'slow');
},
// on mouse out
function () {
// animate opacity to nill
$(this).stop().animate({
opacity: 0
}, 'slow');
});


* This source code was highlighted with Source Code Highlighter.

Объединяя весь Javascript вместе, мы получаем следующее:
<!-- Include jQuery Library -->
<script src="jquery-1.2.2.pack.js" type="text/javascript"></script>
<!-- Let's do the animation -->
<script type="text/javascript">
  $(function() {
    // set opacity to nill on page load
    $("ul#menu span").css("opacity","0");
    // on mouse over
    $("ul#menu span").hover(function () {
      // animate opacity to full
      $(this).stop().animate({
        opacity: 1
      }, "slow");
    },
    // on mouse out
    function () {
      // animate opacity to nill
      $(this).stop().animate({
        opacity: 0
      }, "slow");
    });
  });
</script>


* This source code was highlighted with Source Code Highlighter.

Вначале включаем библиотеку jQuery. Больше об анимации в jQuery можно почитать в документации. Один последний штрих в CSS нам потребуется, чтобы быть уверенными, что курсор отображается как указатель в момент наведения мышкой:
ul#menu li a span:hover {
cursor:pointer;
}

Полный источник кода доступен на демонстрационной странице. Осталось только добавить, что код стабильно работает с Firefox и IE7, а вот IE6 — может и, скорее всего, будет совсем другой историей.

PS
на момент написания статьи автор использовал версию jQuery 1.2.2, в данный момент текущий релиз 1.3.2.
Tags:
Hubs:
+126
Comments 35
Comments Comments 35

Articles