Статьи

Как создать навигационное меню в стиле Lava-Lamp

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

Скриншот

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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<!DOCTYPE html>
 
<html lang=»en»>
<head>
    <meta http-equiv=»Content-Type» content=»text/html; charset=utf-8″>
    <title>SpasticNav Plugin</title>
    <link rel=»stylesheet» href=»css/style.css» type=»text/css» media=»screen» />
</head>
<body>
 
<div id=»container»>
 
    <ul id=»nav»>
        <li id=»selected»><a href=»#»>Home</a></li>
        <li><a href=»#»>About</a></li>
        <li><a href=»#»>Blog</a></li>
        <li><a href=»#»>More About My Portfolio</a></li>
        <li><a href=»#»>Contact</a></li>
    </ul>
 
</div>
 
<script src=»http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js» type=»text/javascript»></script>
 
<script type=»text/javascript» src=»http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js»></script>
      
</body>
</html>

Обратите внимание, как мы дали идентификатор «selected» домашней странице. Это довольно стандартно на большинстве сайтов; это позволяет использовать для таргетинга на текущую страницу и соответственно стилизовать этот конкретный элемент списка

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

1
$(‘#nav’).spasticNav();

Так как мы решили создать плагин, давайте продолжим и создадим новый файл для этого скрипта, и сделаем ссылку на него в нашей разметке. Мы назовем это jquery.spasticNav.js.

1
2
3
4
5
6
<script type=»text/javascript» src=»js/jquery.spasticNav.js»></script>
 
<script type=»text/javascript»>
$(‘#nav’).spasticNav();
</script>
</body>

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

1
2
3
(function($) {
    
})(jQuery);

Теперь jQuery будет передан в наш плагин и будет представлен символом $.

Далее, как правило, рекомендуется предоставить пользователям плагина как можно больше гибкости. Таким образом, мы дадим им возможность передавать объектно-литерал, когда они вызывают плагин для переопределения нескольких настроек. На мой взгляд, они должны быть в состоянии:

  • Установите количество совпадений для нашего маленького шарика. Это относится к тому, насколько BLOB превысит высоту меню навигации.
  • Установить скорость
  • Установите сброс, который заставляет блоб возвращаться к текущему элементу страницы (при условии, что пользователь никогда не нажимает на ссылку)
  • Установите цвет капли. Это можно сделать с помощью CSS, но, тем не менее, это очень удобно.
  • Установите опцию ослабления.

Теперь мы назовем наш плагин и сделаем его равным функции. $ .fn — это просто псевдоним для jquery.prototype.

1
2
3
$.fn.spasticNav = function(options) {
 
};

Зная, что мы будем разрешать эти переопределения, мы должны убедиться, что мы принимаем параметр «options».

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

1
2
3
4
5
6
7
options = $.extend({
    overlap : 20,
    speed : 500,
    reset : 1500,
    color : ‘#0b2b61’,
    easing : ‘easeOutExpo’
}, options);

Выше мы берем переменную options, устанавливаем некоторые свойства и значения по умолчанию, а затем расширяем ее тем, что (если что-нибудь) передает пользователь, когда он вызывает плагин. Таким образом, параметры, которые они передают, переопределяют наши настройки по умолчанию. Например, если при вызове этого плагина я передаю:

1
2
3
4
$(‘#nav’).spasticNav({
   speed : 2000,
   easing : ‘easeOutElastic’
});

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

Теперь мы готовы пройтись по каждому элементу, который был передан этому плагину, и реализовать функциональность lava-lamp. Помните, мы не можем предполагать, что пользователь собирается передать один элемент этому плагину. При желании они могут ссылаться на класс, который ссылается на несколько элементов, которые должны получить эту функциональность. Поэтому мы будем вызывать this.each для перебора каждого элемента в упакованном наборе.

1
2
3
return this.each(function() {
 
});

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

1
2
3
4
var nav = $(this),
    currentPageItem = $(‘#selected’, nav),
    blob,
    reset;
  • nav: «Кэши» это , завернутый в объект jQuery.
  • currentPageItem: Содержит элемент списка с идентификатором выбранного. Мы передаем второй параметр, чтобы установить контекст для поиска. Таким образом, нам не нужно проходить через весь дом, чтобы найти этот элемент.
  • blob: из- за отсутствия лучшего слова, эта переменная будет ссылаться на маркер, который будет следовать за нашей мышью, когда мы наводим курсор мыши на меню.
  • сброс: будет сохранена ссылка на функцию setTimeout, которая будет создана позже. Это нужно для вызова clearTimeout. Подробнее об этом скоро …

Теперь, когда мы объявили / инициализировали наши переменные, давайте создадим, так сказать, настоящий BLOB-объект.

1
2
3
4
5
6
7
$(‘<li id=»blob»></li>’).css({
    width : currentPageItem.outerWidth(),
    height : currentPageItem.outerHeight() + options.overlap,
    left : currentPageItem.position().left,
    top : currentPageItem.position().top — options.overlap / 2,
    backgroundColor : options.color
}).appendTo(this);

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

  • width: Получить ширину currentPageItem, включая любые границы и отступы.
  • высота: получить высоту currentPageItem, включая любые границы и отступы. Кроме того, добавьте количество совпадений, чтобы капля расширялась за пределы меню.
  • left: Устанавливает свойство left объекта blob, равное левой позиции currentPageItem. (Мы должны установить контекст позиционирования в нашем CSS, чтобы это значение вступило в силу.)
  • top: также устанавливает верхнее значение и центрирует каплю по вертикали.
  • backgroundColor: устанавливает цвет фона.

Наконец, мы добавляем этот новый элемент списка к этому , или #nav.

Далее нам нужно сохранить ссылку на #blob. Таким образом, нам не нужно искать DOM каждый раз, когда мы хотим получить к нему доступ. Мы объявили переменную blob вверху функции. Теперь давайте инициализируем это.

1
blob = $(‘#blob’, nav);

Теперь мы должны «слушать», когда пользователь наводит курсор на один из элементов списка (за исключением, конечно, большого двоичного объекта) в нашем меню навигации. Когда они это сделают, мы установим свойства ширины и левого объекта BLOB-объекта равными свойствам текущего элемента списка.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$(‘li:not(#blob)’, nav).hover(function() {
    // mouse over
    clearTimeout(reset);
    blob.animate(
        {
            left : $(this).position().left,
            width : $(this).width()
        },
        {
            duration : options.speed,
            easing : options.easing,
            queue : false
        }
    );
}, function() {
    // mouse out
    reset = setTimeout(function() {
        blob.animate({
            width : currentPageItem.outerWidth(),
            left : currentPageItem.position().left
        }, options.speed)
    }, options.reset);
     
});

Подводя итог сценария выше …

  • Получить все элементы списка — не #blob — в меню навигации, и когда они наведутся, запустите функцию.
  • Анимируйте BLOB-объект и установите его значения влево и ширину, равные значению элемента списка.
  • Передайте литерал объекта в качестве второго параметра animate и установите длительность и замедление, равные значениям, указанным в наших параметрах конфигурации. Установите очередь в false, чтобы предотвратить наращивание анимации.
  • Когда они наведут курсор мыши, вызовите setTimeOut, который вернет BLOB-объект к текущему элементу страницы. Если мы этого не сделаем, а пользователь не нажмет на навигационную ссылку, меню покажет, что он включен
    совсем другая страница. Это примерно через секунду оживит BLOB-объект обратно в currentPageItem.

И это все, что нужно сделать! Это супер простой плагин. Следующим шагом будет стиль нашего навигационного меню.

Без какого-либо стиля наше меню должно выглядеть примерно так:

Неустановленная наценка

Давайте сначала стилизовать «nav» ul. Откройте файл style.css и добавьте:

1
2
3
4
5
#nav {
    position: relative;
    background: #292929;
    float: left;
}
Стилизация меню навигации

Далее мы будем стилизовать каждый элемент списка.

1
2
3
4
5
6
#nav li {
    float: left;
    list-style: none;
    border-right: 1px solid #4a4a4a;
    border-left: 1px solid black;
}

Это просто перемещает каждый элемент списка влево и добавляет границу к каждой стороне.

Стилизация элементов списка

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

01
02
03
04
05
06
07
08
09
10
#nav li a {
    color: #e3e3e3;
    position: relative;
    z-index: 2;
    float: left;
    font-size: 30px;
    font-family: helvetica, arial, sans-serif;
    text-decoration: none;
    padding: 30px 45px;
}

Мы устанавливаем цвет, перемещаем их влево, устанавливаем некоторые значения шрифта и достаточное количество отступов. Обратите внимание на свойство z-index. Это необходимо, и будет объяснено в ближайшее время. Однако помните, что для настройки z-индекса мы должны установить контекст позиционирования, что мы и сделали.

Стилизация якорных тегов

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

1
2
3
ul, li {
    margin: 0;
}

Последний шаг — стилизация самого блоба!

01
02
03
04
05
06
07
08
09
10
11
12
13
14
#blob {
    border-right: 1px solid #0059ec;
    border-left: 1px solid #0059ec;
    position: absolute;
    top: 0;
    z-index : 1;
    background: #0b2b61;
    background: -moz-linear-gradient(top, #0b2b61, #1153c0);
    background: -webkit-gradient(linear, left top, left bottom, from(#0b2b61), to(#1153c0));
    -moz-border-radius: 4px;
    -webkit-border-radius: 4px;
    -moz-box-shadow: 2px 3px 10px #011331;
    -webkit-box-shadow: 2px 3px 10px #011331;
}

Еще раз, мы установили несколько красивых цветов для наших границ и добавили некоторые цвета фона (в том числе CSS3 градиенты / границы / тени для Firefox и Safari / Chrome). Еще раз, мы видим это свойство z-index. Без этого блоб будет отображаться над всем текстом в меню навигации. Чтобы противостоять этому, мы должны быть уверены, что его свойство z-index НИЖЕ, чем у элемента списка! Мы также должны установить абсолютное положение, чтобы скорректировать его верхнее и левое значения с помощью нашего плагина.

Скриншот

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