Анимированное меню с помощью jQuery
Сегодня мы создадим отличное анимированное меню для сайта ресторана. Пункты меню будут анимированы, а при клике по одному из них будет выплывать окошко с контентом. К тому же, фоновое изображение будет меняться в зависимости от того, какой пункта меню был открыт.
У нас будут отображены категории меню ресторана. В каждом блоке с контентом будут перечислены какие-то напитки и блюда. Сразу после появления блока с контентом меню скроется. При клике по кнопке закрытия, контент скроется и отобразится меню.
Итак, начнем!
Структура
В HTML у нас будут несколько элементов для фонового изображения, сетки, перекрывающей его, иконки загрузки и главного меню. Структура будет выглядеть так:
<div id="ac_background" class="ac_background"> <img class="ac_bgimage" src="/images/Default.jpg" alt="Фон"/> <div class="ac_overlay"></div> <div class="ac_loading"></div> </div>
После загрузки страницы отобразится изображение по умолчанию Default.jpg. При клике по какому-то пункту меню, фоновое изображение будет перекрываться другим, а само оно исчезнет.
Меню заключим в блок div с классом “ac_content”. Здесь будет размещен заголовок и ненумерованный список для пунктов меню, заключенный в div с классом “ac_menu”.
<div id="ac_content" class="ac_content"> <h1><span>Cafe + Bar</span>Dhalia</h1> <div class="ac_menu"> <ul> <li> <a href="/images/Appetizers.jpg">Appetizers</a> <div class="ac_subitem"> <span class="ac_close"></span> <h2>Appetizers</h2> <ul> <li> A wonderful serenity has taken possession of my entire soul, like these sweet mornings of spring which I enjoy with my whole heart. </li> <li>Lobster Bisque</li> <li>Smoked Salmon Terrine</li> <li>Tuna Ceviche</li> <li>Wild Mushroom Flan</li> <li>Almond Bruschetta</li> <li>Green Chilli Canapee</li> <li>Artichoke Rucula Salad</li> </ul> </div><!-- ac_subitem--> </li> ... </ul> </div><!-- ac_menu --> </div><!-- ac_content -->
Для каждого пункта меню создадим блок div с классом “ac_subitem”, в котором будет содержаться контент. Сюда мы поместим другой список (не обязательно список, можно все, что угодно).
Ссылки в главном меню будут вести к изображениям, которые отобразятся при клике на соответствующий пункт меню.
Теперь давайте разберемся со стилями.
CSS
В самом начале давайте подключим файл reset.css:
@import url('reset.css');
Фоновый цвет элемента body будет черным, чтобы они темнели во время того, как одно изображение будет сменяться другим.
body{ background:#000; color:#fff; font-family: 'PT Sans Narrow', Arial, sans-serif; text-transform:uppercase; }
Цвет текста под ссылки будет белым:
a{ color:#fff; text-decoration:none; }
Фоновые изображения будут назначаться с помощью JavaScript, поэтому мы не назначим ни одного из них через CSS. Размеры и расположение изображений также будут считаться динамически и будут зависеть от размеров пользовательских мониторов:
img.ac_bgimage{ position:fixed; left:0px; top:0px; opacity:0.8; display:none; }
Поверх изображения отобразим специальный паттерн, который придаст ему красивый вид:
.ac_overlay{ width:100%; height:100%; position:fixed; top:0px; left:0px; background:transparent url(../images/pattern.png) repeat top left; }
Иконку загрузки поместим в правый верхний угол страницы. Она будет отображаться во время смены изображений:
.ac_loading{ position:fixed; top:10px; right:10px; background:#000 url(../images/loader.gif) no-repeat center center; width:50px; height:50px; border-radius:10px 10px 10px 10px; z-index:999; opacity:0.7; display:none; }
Блок с контентом расположим в центре страницы. Для этого присвоим атрибуту top значение 50% и уменьшим его высоту, присвоив атрибуту margin-top значение -65px. Так он расположится прямо по центру:
.ac_content{ position:fixed; height:90px; width:100%; top:50%; left:0px; margin-top:-65px; }
Фон под заголовком слева будет черным полу-прозрачным. Стили для заголовка h1 и span мы определим отдельно. Справа добавим рамку толщиной в 1 пиксель, чтобы визуально отделить заголовок от меню:
.ac_content h1{ background:transparent url(../images/bg_menu.png) repeat top left; display:block; float:left; width:90px; height:50px; padding:20px; font-size:36px; font-weight:bold; line-height:20px; margin-right:1px; } .ac_content h1 span{ display:block; font-weight:normal; font-size:14px; }
Фон блока меню будет таким же. Начальная его ширина будет 0 пикселей. Через JavaScript мы увеличим ее до ширины окна при загрузке страницы:
.ac_menu{ background:transparent url(../images/bg_menu.png) repeat top left; float:left; position:relative; height:90px; width:0px; }
Для ненумерованного списка с пунктами меню определим такой стиль:
.ac_menu > ul{ float:right; }
Высота элементов списка будет подсчитана определенным образом, для них мы также зададим атрибут overflow: hidden, так как нам необходимо, чтобы они выплывали снизу. Если не задать атрибут overflow: hidden, то ссылки будут видны во время анимации:
.ac_menu > ul > li{ float:left; position:relative; height:90px; overflow:hidden; }
Изначально ссылки будут скрыты с помощью задания атрибутов margin-top и opacity. После мы плавно переместим их на середину (margin-top: 0px) и сделаем их видимыми, увеличив значение opacity. Причем сделаем это так, чтобы они немножко задерживались, тем самым создадим интересный эффект:
.ac_menu > ul > li a{ margin-top:60px; opacity:0; display:block; height:90px; padding:0px 10px; text-align:center; line-height:90px; outline:none; font-size:18px; font-weight:bold; text-shadow:1px 1px 1px #000; }
Блоки с контентом будут шириной в 400 пикселей и начальной высотой в 0 пикселей. Мы плавно увеличим это значение потом, а также значение margin-top, чтобы окошко появлялось из середины:
.ac_subitem{ width:400px; height:0px; /* animate to 400px */ top:50%; right:0px; margin-top:0px; /* animate to -200px */ position:fixed; z-index:99; overflow:hidden; background:transparent url(../images/bg_menu.png) repeat top left; }
Определим также некоторые стили для блока с контентом:
.ac_subitem h2{ font-size:22px; font-weight:bold; color:#fff; padding: 40px 0px 0px 40px; text-shadow:0px 0px 1px #000; } .ac_subitem ul{ padding:0px 40px; } .ac_subitem ul li{ margin:10px 0px; } .ac_subitem ul li:first-child{ font-size:14px; text-transform:none; border-bottom:1px dotted #333; padding-bottom:15px; margin-bottom:15px; }
Добавим иконку закрытия данного блока в его правый верхний угол:
span.ac_close{ float:right; margin:10px; width:11px; height:12px; cursor:pointer; background:transparent url(../images/close.png) no-repeat top left; opacity:0.4; } span.ac_close:hover{ opacity:1.0; }
Это все насчет стиля. Перейдем к анимации.
JavaScipt
Для анимации мы будем использовать дополнительный плагин. Подключите его сразу после подключения jQuery.
Сперва объявим переменные:
var $ac_background = $('#ac_background'), $ac_bgimage = $ac_background.find('.ac_bgimage'), $ac_loading = $ac_background.find('.ac_loading'), $ac_content = $('#ac_content'), $title = $ac_content.find('h1'), $menu = $ac_content.find('.ac_menu'), $mainNav = $menu.find('ul:first'), $menuItems = $mainNav.children('li'), totalItems = $menuItems.length, $ItemImages = new Array();
Загрузим все изображения, так что добавим все ссылки, а также дополнительно объявим текущее изображение:
$menuItems.each(function(i) { $ItemImages.push($(this).children('a:first').attr('href')); }); $ItemImages.push($ac_bgimage.attr('src')); А теперь приступим к нашей главной функции: var Menu = (function(){ var init = function() { loadPage(); initWindowEvent(); }, loadPage = function() { /* 1- загружает все фоновые и другие изображения; 2- отображает фоновое изображение; 3- скрывает и открывает меню; 4- отображает пункты меню; 5- инициализирует события, связанные с пунктами меню */ $ac_loading.show(); //отображение иконки загрузки $.when(loadImages()).done(function(){ $.when(showBGImage()).done(function(){ //скрывает иконку загрузки $ac_loading.hide(); $.when(slideOutMenu()).done(function(){ $.when(toggleMenuItems('up')).done(function(){ initEventsSubMenu(); }); }); }); }); }, showBGImage = function() { return $.Deferred( function(dfd) { //подсчитывает размеры изображения adjustImageSize($ac_bgimage); $ac_bgimage.fadeIn(1000, dfd.resolve); } ).promise(); }, slideOutMenu = function() { /* подсчитывает новую ширину меню */ var new_w = $(window).width() - $title.outerWidth(true); return $.Deferred( function(dfd) { //скрывает меню $menu.stop() .animate({ width : new_w + 'px' }, 700, dfd.resolve); } ).promise(); }, /* скрывает / отображает пункт меню */ toggleMenuItems = function(dir) { return $.Deferred( function(dfd) { /* скрывает / отображает пункты меню. каждый раз разная анимация. */ $menuItems.each(function(i) { var $el_title = $(this).children('a:first'), marginTop, opacity, easing; if(dir === 'up'){ marginTop = '0px'; opacity = 1; easing = 'easeOutBack'; } else if(dir === 'down'){ marginTop = '60px'; opacity = 0; easing = 'easeInBack'; } $el_title.stop() .animate({ marginTop : marginTop, opacity : opacity }, 200 + i * 200 , easing, function(){ if(i === totalItems - 1) dfd.resolve(); }); }); } ).promise(); }, initEventsSubMenu = function() { $menuItems.each(function(i) { var $item = $(this), //$el_title = $item.children('a:first'), el_image = $el_title.attr('href'), $sub_menu = $item.find('.ac_subitem'), $ac_close = $sub_menu.find('.ac_close'); /* пользователь кликает по пункту меню */ $el_title.bind('click.Menu', function(e) { $.when(toggleMenuItems('down')).done(function(){ openSubMenu($item, $sub_menu, el_image); }); return false; }); /* контент скрывается */ $ac_close.bind('click.Menu', function(e) { closeSubMenu($sub_menu); return false; }); }); }, openSubMenu = function($item, $sub_menu, el_image) { $sub_menu.stop() .animate({ height : '400px', marginTop : '-200px' }, 400, function() { //the bg image changes showItemImage(el_image); }); }, /* меняется фоновое изображение */ showItemImage = function(source) { //если это текущее изображение, то вернет 0 if($ac_bgimage.attr('src') === source) return false; var $itemImage = $(''); $itemImage.insertBefore($ac_bgimage); adjustImageSize($itemImage); $ac_bgimage.fadeOut(1500, function() { $(this).remove(); $ac_bgimage = $itemImage; }); $itemImage.fadeIn(1500); }, closeSubMenu = function($sub_menu) { $sub_menu.stop() .animate({ height : '0px', marginTop : '0px' }, 400, function() { //отображение элементов toggleMenuItems('up'); }); }, /* on window resize, ajust the bg image dimentions, and recalculate the menus width */ initWindowEvent = function() { /* назначает ширину фонового изображения */ $(window).bind('resize.Menu' , function(e) { adjustImageSize($ac_bgimage); /* считает новую ширину меню */ var new_w = $(window).width() - $title.outerWidth(true); $menu.css('width', new_w + 'px'); }); }, /* расширяет изображение и располагает его по центру */ adjustImageSize = function($img) { var w_w = $(window).width(), w_h = $(window).height(), r_w = w_h / w_w, i_w = $img.width(), i_h = $img.height(), r_i = i_h / i_w, new_w,new_h, new_left,new_top; if(r_w > r_i){ new_h = w_h; new_w = w_h / r_i; } else{ new_h = w_w * r_i; new_w = w_w; } $img.css({ width : new_w + 'px', height : new_h + 'px', left : (w_w - new_w) / 2 + 'px', top : (w_h - new_h) / 2 + 'px' }); }, /* загружает все изображения */ loadImages = function() { return $.Deferred( function(dfd) { var total_images = $ItemImages.length, loaded = 0; for(var i = 0; i < total_images; ++i){ $('').load(function() { ++loaded; if(loaded === total_images) dfd.resolve(); }).attr('src' , $ItemImages[i]); } } ).promise(); }; return { init : init }; })(); /* вызов метода init */ Menu.init();
На этом все. Надеюсь, вам понравился урок!
Источник: http://feedproxy.google.com/~r/ruseller/CdHX/~3/DFtJ5XshtJk/lessons.php
Дайджест новых статей по интернет-маркетингу на ваш email
Новые статьи и публикации
- 2024-11-26 » Капитан грузового судна, или Как начать использовать Docker в своих проектах
- 2024-11-26 » Обеспечение безопасности ваших веб-приложений с помощью PHP OOP и PDO
- 2024-11-22 » Ошибки в Яндекс Вебмастере: как найти и исправить
- 2024-11-22 » Ошибки в Яндекс Вебмастере: как найти и исправить
- 2024-11-15 » Перенос сайта на WordPress с одного домена на другой
- 2024-11-08 » OSPanel 6: быстрый старт
- 2024-11-08 » Как установить PhpMyAdmin в Open Server Panel
- 2024-09-30 » Как быстро запустить Laravel на Windows
- 2024-09-25 » Next.js
- 2024-09-05 » OpenAI рассказал, как запретить ChatGPT использовать содержимое сайта для обучения
- 2024-08-28 » Чек-лист: как увеличить конверсию интернет-магазина на примере спортпита
- 2024-08-01 » WebSocket
- 2024-07-26 » Интеграция с Яндекс Еда
- 2024-07-26 » Интеграция с Эквайринг
- 2024-07-26 » Интеграция с СДЕК
- 2024-07-26 » Интеграция с Битрикс-24
- 2024-07-26 » Интеграция с Travelline
- 2024-07-26 » Интеграция с Iiko
- 2024-07-26 » Интеграция с Delivery Club
- 2024-07-26 » Интеграция с CRM
- 2024-07-26 » Интеграция с 1C-Бухгалтерия
- 2024-07-24 » Что такое сторителлинг: техники и примеры
- 2024-07-17 » Ошибка 404: что это такое и как ее использовать для бизнеса
- 2024-07-03 » Размещайте прайс-листы на FarPost.ru и продавайте товары быстро и выгодно
- 2024-07-01 » Профилирование кода в PHP
- 2024-06-28 » Изучаем ABC/XYZ-анализ: что это такое и какие решения с помощью него принимают
- 2024-06-17 » Зачем вам знать потребности клиента
- 2024-06-11 » Что нового в работе Яндекс Метрики: полный обзор обновления
- 2024-06-11 » Поведенческие факторы ранжирования в Яндексе
- 2024-06-11 » Скорость загрузки сайта: почему это важно и как влияет на ранжирование
Все мы сидим в сточной канаве, но некоторые при этом смотрят на звезды Уайльд Оскар - (1854-1900) - английский писатель |
Мы создаем сайты, которые работают! Профессионально обслуживаем и продвигаем их , а также по всей России и ближнему зарубежью с 2006 года!
Как мы работаем
Заявка
Позвоните или оставьте заявку на сайте.
Консультация
Обсуждаем что именно Вам нужно и помогаем определить как это лучше сделать!
Договор
Заключаем договор на оказание услуг, в котором прописаны условия и обязанности обеих сторон.
Выполнение работ
Непосредственно оказание требующихся услуг и работ по вашему заданию.
Поддержка
Сдача выполненых работ, последующие корректировки и поддержка при необходимости.