SiteIS

jQuery - безграничные возможности в дизайне Вашего сайта!

- Один из самых популярных на сегодня среди веб разработчиков фреймворк

- Позволяет быстро и легко создать потрясающие веб-приложения

- Удивительно красивые анимационные эффекты

- Улучшение пользовательского интерфейса

Простейший аккордеон

В этот раз мы сделаем нечто более востребованное, нежели эффект зебры. Мы реализуем панель типа аккордеон. Использовать ее в дальнейшем можно по разному - выпадающее вертикальное меню, оформление страницы "вопрос-ответ" и т.д. Тут полет фантазии не ограничен.

Разметку можно выполнить по разному. В этот раз реализуем вариант на основе списков. Вот что у нас должно получиться в итоге:

простейший аккордеон

При клике по пунктам Новости и О нас должны будут открываться подпункты этих категорий. При повторном клике по названиям категорий подпункты должны прятаться.

Вспоминаем основы (добрый день html и css) и набросаем, ставшую классикой, разметку для выпадающих меню из четырех пунктов, два из которых будут иметь вложенные списки:

<ul>
	<li><a href="#">Главная</a></li>
	<li><a href="#">Новости</a>
		<ul>
			<li><a href="#">Хроника</a></li>
			<li><a href="#">Политика</a></li>
			<li><a href="#">Спорт</a></li>
			<li><a href="#">За рубежом</a></li>
		</ul>	
	</li>
	<li><a href="#">О компании</a>
		<ul>
			<li><a href="#">Отзывы</a></li>
			<li><a href="#">События</a></li>
		</ul>	
	</li>
	<li><a href="#">Связь с нами</a></li>
</ul>

С помощью css придадим менюшке приличный внешний вид. что бы оно выглядело, как на картинке:

ul  {
margin:20px;
width:200px;
list-style:none;
}
li a {
padding:5px 10px;
display:block;
font-size:14px;
font-weight:bold;
color:#000;
text-decoration:none;
background:#e4e7ea;
border-bottom:1px solid #d4d9df
}

ul ul  {
margin:0;
display:none;
}
ul ul a  {
padding-left:20px;
font-size:12px;
color:#8b8b8b;
background:#ededed;
}

Глянем в браузере на результат. Все выглядит как нужно, вот только если пощелкать по ссылкам, увы, ничего не происходит - меню не работает (под категории не открываются). Исправлять этот недочет будем, как нетрудно догадаться, с помощью jQuery.

Используем click(), next() и toggle():

$(function () {
	$('ul li a').click(function() {
		$(this).next().toggle(500);
	});
});

Тут все просто, отбираем в набор ссылки, которые находятся внутри элемента li, ожидаем пока по ним кликнут и с помощью метода toggle() делаем видимым соседний со ссылкой элемент. По коду это элемент вложенный ul, который является родителем для подменю и имеет в css стиль display:none. Метод toggle() присвоит ему значение display:block и элемент станет видимым. Повторный клик по той же ссылке вернет элементу ul его начальное значение. Для более плавного появления/исчезновения субменю, методу toggle() можно передать параметр в миллисекундах, за который он будет отображать/прятать элемент.

Посмотрим на результаты проделанной работы. При клике на ссылках "Новости" и "О нас" подменю появляется, если оно было скрыто при повторном клике прячется. Только вот не очень то мне нравится его появление... Метод toggle() использует методы hide() и show(), которые, на мой взгляд, не подходят к данной ситуации (впрочем, может кому то и понравится).

Давайте изменим js так, что бы субменю открывались в виде слайдера. Перепишем код, используя методы click(), next(), animate() и toggle():

$(function () {
	$('ul li a').click(function() {
		$(this).next().animate({'height':'toggle'}, 500);
	});
});

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

Представьте, что меню расположено не в самом верху страницы, а где нибудь в центре экрана (этого легко добиться, если установить в css верхний отступ для body 200 - 300px). Теперь, если проскролить страницу к самому низу и кликнуть по любому пункту меню, то будет наблюдаться резкий скачек вверх. Это происходит каждый раз, когда мы кликаем на "пустую" (никуда не ведущую) ссылку. Казалось бы - исправить недочет просто. Запретим переход по ссылкам и будет нам счастье. Благо в jQuery это можно сделать двумя способами - либо просто написать return false;, либо использовать функцию, отменяющую события по умолчанию preventDefault();.

$(function () {
	$('ul li a').click(function() {
		$(this).next().animate({'height':'toggle'}, 500);
                return false;
	});
});

//или

$(function () {
	$('ul li a').click(function(event) {
		$(this).next().animate({'height':'toggle'}, 500);
                event.preventDefault();
	});
});

Отлично - страница перестала скакать. Но теперь, если в подменю задать ссылке реальный путь, то никакого перехода не будет - мы же запретили это действие. Придется изобретать что то другое. Самое первое, что по идее приходит в голову, запретить переход только для тех ссылок, которые являются ссылками верхнего уровня и имеют вложенные пункты. Что ж, давайте попробуем - создадим переменную в которой будем хранить элемент, являющийся следующим для текущей ссылки и условие, в котором будем проверять, если этот элемент ul и он видимый, то запрещаем переход.

И еще одна маленькая деталь. Если пользователь быстро кликнет по пункту меню несколько раз, то анимация отработает для каждого клика. В этом случае меню покажется и спрячется столько раз, сколько было сделано щелчков. Что бы избавится от этого нежелательного действия, воспользуемся методом stop().

$(function () {
	$('ul li a').click(function() {
                var checkElement = $(this).next();
		checkElement.stop().animate({'height':'toggle'}, 500);
		if((checkElement.is('ul')) && (checkElement.is(':visible'))) {
			return false;
		}
	});
});

//или

$(function () {
	$('ul li a').click(function(event) { 
                var checkElement = $(this).next();
		checkElement.stop().animate({'height':'toggle'}, 500);
		if((checkElement.is('ul')) && (checkElement.is(':visible'))) {
			event.preventDefault();
		}
	});
});

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

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

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

Исходный код окончательного варианта можно скачать по ссылке ниже.

Скачать готовый код

Автор: Super User

Комментарии  

 
+1 # Евгений 17.07.2013 10:19
Как сделать чтобы открыв один список, все осталньые были закрыты?
Ответить | Ответить с цитатой | Цитировать
 
 
0 # admin 17.07.2013 12:52
В следующих статьях раздела
/izuchaem-jquery/rasshiryaem-funktsionalnost-akkordiona
или
/izuchaem-jquery/uluchshaem-akkordeon-bez-spiskov
описано как реализовать нужный вам вариант.
Так же можно обратиться к материалам
/jquery-v-primerakh/jqurey-menyu/menyu-akkordeon
или
/jquery-v-primerakh/jqurey-menyu/blochnyj-akkordeon
в которых представлен код нескольких вариантов без подробного описания
Ответить | Ответить с цитатой | Цитировать