css, html, php, javascript, jQuery, ajax … – решения, примеры, рецепты
26 Июн
jQuery UI – надстройка над JavaScript-библиотекой jQuery. Она поможет создавать по настоящему интерактивные веб-приложения. Сегодня мы познакомимся с виджетом Accordion.

Щелчок по заголовку скрывает/отображает содержимое, разбитое на логические секции. При отображении содержимого одной секции, открытая ранее секция обязательно закрывается.
Для начала посетим страницу настраиваемой закачки на сайте jQuery UI, чтобы получить необходимые нам файлы. Щелкаем на ссылке Deselect all component , чтобы не закачивать лишнее, а затем выбираем только то, что нам потребуется – отмечаем чекбокс accordion и видим, что вместе с ним отметился чекбокс UI Core. Работа виджета Accordion зависит от него, поэтому он необходим.
Кроме этого, справа есть выпадающий список, где можно выбрать понравившуюся тему оформления. Если все готово, кликаем кнопку Download и получаем архив. Можно испытать пример как есть, но интереснее создать свою HTML-страничку, где сначала в разделе HEAD подключить несколько файлов, которые есть в архиве.
<link type="text/css" href="css/smoothness/jquery-ui-1.7.1.custom.css" rel="stylesheet" /> <script src="js/jquery-1.3.2.min.js" type="text/javascript"></script> <script src="js/jquery-ui-1.7.1.custom.min.js" type="text/javascript"></script>
Мы подключили файл стилевого оформления виджета, файл библиотеки jQuery. В третьем файле объединена функциональность ядра UI и виджета Accordion.
Двигаемся дальше и замечаем, что Accordion предъявляет некоторые требования к HTML-разметке.
<div id="accordion"> <h3><a href="#">Section 1</a></h3> <div>Section 1 content</div> <h3><a href="#">Section 2</a></h3> <div>Section 2 content</div> <h3><a href="#">Section 3</a></h3> <div>Section 3 content</div> </div>
Обратите внимание, что по умолчанию виджет считает заголовками секций элементы a (в нашем примере они заключены в тэг h3), а содержимое секций должно быть заключено в следующий непосредственно за ним элемент div. Внутри элемента div содержимое может быть практически любым.
Осталось привязать функциональность виджета к HTML-разметке. Это просто:
<script type="text/javascript">
$(function(){
$("#accordion").accordion();
});
</script>
Все! Accordion уже работает! Правда использует он пока все настройки по умолчанию, а мы хотим настроить его под себя. Это тоже несложно. Передадим виджету пару настроек.
<script type="text/javascript">
$(function(){
$("#accordion").accordion({
autoHeight: false,
active: 2
});
});
</script>
По умолчанию у аккордеона открывалась первая секция, высота всех секций была одинаковая и равна высоте секции с максимальным количеством содержимого. Передав пару настроек мы добились того, что по умолчанию открывается третья секция и каждая секция имеет высоту, соответствующую ее содержимому.
Мы использовали только две настройки, но их значительно больше и с их помощью можно очень гибко настраивать виджет. Ниже приведен список возможных опций с описаниями.
active – Выбирает секцию, открытую при инициализации. По умолчанию имеет значение first child, т.е. открывается первая секция. Установка значения в false не приведет к тому, что все секции будут закрыты. Для того чтобы иметь возможность закрывать все секции используется collapsible: true.
animated – Включает или отключает анимацию. Установка опции в false отключит анимацию, применяемую по умолчанию (эффект скольжения). Дополнительно поддерживаются эффекты ‘bounceslide’ and ‘easeslide’, но оба эффекта требуют подключения дополнительного плагина jQuery Easing.
autoHeight – Автоматическая установка высота секции. По умолчанию используется значение true и высота всех секций определяется секцией с максимальной высотой. При установке значения false все секции будут иметь высоту, определяемую внутренним содержимым секции.
clearStyle – По умолчанию используется значение false. Если установить значение true, то после окончания анимации будут очищены css-свойства height и overflow. Эта опция позволяет работать с динамически изменяемым содержимым секций. Не используется вместе с опцией autoHeight.
collapsible – По умолчанию используется значение false. Если при инициализации установить значение true, можно будет закрывать открытую секцию щелчком по заголовку, таким образом, чтобы все секции были закрыты.
event Определяет событие, по которому происходит переключение секций. По умолчанию установлено значение ‘click’. Можно использовать значение ‘mouseover’.
fillSpace – По умолчанию опция имеет значение false. При установке значения true открытая секция будет занимать всю возможную высоту, определяемую родительским элементом. Переопределяет опцию autoHeight.
header – По умолчанию заголовком секции считается элемент a. Но заголовок можно определить явно, например header: ‘h3′.
icons – Значки для использования в заголовках. Это объект, состоящий из двух пар ключ/значение. Может быть определен как ‘header’: ‘ui-icon-plus’ и ‘headerSelected’: ‘ui-icon-minus’. Значения являются именами классов css, с помощью которых выбирается соответствующая картинка. Рекомендуется использовать значки, предоставляемые jQuery UI ThemeRoller вместе с многочисленными вариантами стилевого оформления.
navigation – По умолчанию используется значение false. Если установить true, разыскивает и активирует ссылку. Используется, как правило, для построения меню на основе виджета, поскольку при перезагрузке страницы позволяет сохранить состояние. Обычно применяют HTML-разметку на основе списков.
navigationFilter – В этой опции можно определить функцию, которая будет каким-либо образом обрабатывать ссылку, по которой осуществляется переход. Используется совместно с опцией navigation.
Однако это еще не все. Кроме возможности довольно гибко настроить виджет, можно заставить его реагировать на события. Очень простой пример
<script type="text/javascript">
$(function(){
$("#accordion").accordion({
autoHeight: false,
active: 2,
change: function(event, ui) {
alert("Произошло событие " + event.type);
}
});
});
</script>
Обратите внимание на опцию change, значением которой является callback-функция, вызываемая при смене секции. Эта callback-функция может принимать два аргумента. Первый – это обычный объект event, второй аргумент – объект ui, в свойствах которого содержится следующая информация:
ui.newHeader – объект jQuery с информацией об активируемом заголовке;
ui.oldHeader – объект jQuery с информацией о предыдущем заголовке;
ui.newContent – объект jQuery с информацией об активируемом содержимом;
ui.oldContent – объект jQuery с информацией о предыдущем содержимом;
И пример того, как можно обратиться к свойствам этих объектов:
<script type="text/javascript">
$(function(){
$("#accordion").accordion({
autoHeight: false,
active: 2,
change: function(event, ui) {
alert("Старый заголовок: " +
ui.oldHeader.find("a").text() +
"\nНовый контент: " +
ui.newContent.text());
}
});
});
</script>
Опций, связанных с событиями всего две:
Опция changestart – Событие accordionchangestart наступает каждый раз при начале смены секций.
Опция change – Событие accordionchange наступает каждый раз после того, как изменилась активная секция. Если используется анимация, то событие наступает по ее завершении, если нет – то событие наступает немедленно.
Нам осталось познакомиться с методами виджета Accordion. В следующем примере продемонстрировано как с помощью метода option можно получить и установить значения опций уже после инициализации виджета. Для этого придется в HTML-код с которым мы эксперементируем, добавить пару кнопок:
<button id="getter">Get Option</button> <button id="setter">Set Option</button>
и пример javascript-кода:
<script type="text/javascript">
$(function(){
$("#accordion").accordion({
autoHeight: false,
active: 2,
animated: false
});
$("#getter").click(function(){
alert("animated: " +
$("#accordion").accordion("option","animated"));
});
$("#setter").click(function(){
$("#accordion").accordion("option","animated","slide");
alert("animated: " +
$("#accordion").accordion("option","animated"));
});
});
</script>
При инициализации виджета, мы использовали опцию animated: false, отключив, таким образом, применяемую по умолчанию анимацию. Попробуйте переключать секции и убедитесь в том, что никаких эффектов при переключении действительно нет. Если щелкнуть по кнопке Get Option, мы увидим окно предупреждения, в котором будет выведено текущее значение опции animated. Изменим значение этой опции на slide, щелкнув по кнопке Set Option. Получили окно предупреждения с сообщением: animated: slide. Проверим это, переключая секции. Действительно, теперь при переключении секций используется анимация.
Ну, а ниже описаны все возможные методы виджета Accordion:
destroy – .accordion(«destroy») полностью удаляет всю функциональность виджета Accordion. Возвращает элементы в состояние, предшествующее инициализации.
disable – .accordion(«disable») временно запрещает использование всей функциональности виджета. Вновь разрешить ее использование можно с помощью метода enable.
enable – .accordion(«enable») разрешает использование всей функциональности виджета, если ранее она была запрещена с использованием метода disable.
option – .accordion(«option», optionName, [value]) с помощью этого метода можно получить или установить значение любой опции виджета после инициализации.
activate – .accordion(«activate» , index) с помощью этого метода можно программно активировать необходимые секции. Аргумент index может быть номером секции (отсчет ведется от 0) или селектором jQuery, который выберет необходимый элемент. Передавая значение -1 можно закрыть все секции (только в случае использования опции collapsible:true).
На этом пока закончим, хотя и остались неосвещенными вопросы построения на базе виджета Accordion навигационного меню и мы почти не рассматривали стилевое оформление виджета. Но статья и так получилась довольно громоздкой, а к упомянутым темам, надеюсь, еще удастся вернуться позже.
Отзывов (58) на «jQuery UI – виджет Accordion»
Замечательно. А то старая статья про аккордион уже устарела…
Во, блин, огромное спасибо (-:
Особенно порадовало то, как указать, что активная та или иная вкладка, никак не доходили руки разобраться с этим (-:
Ещё у меня была куча вопросов с изменением цвета, чтоб подогнать под свои нужды… методом проб и ошибок всё-таки сделал (-:
Хорошая статья по jquery ui. Спасибо.
Классный видж!
Очень интересует горизонтальный аккордеон с картинками и выезжающим текстом! Может просветите? Буду очень благодарен!
Например как тут, только черточки надо убрать, w_w_w.f_u_t_s_a_l_d_n_e_p_r.n_a_r_o_d.r_u/comand/accordeon.html Только в ie6 почему-то глючит, помогите пожалуйста разобраться!
Ребята! Давайте после 22-го числа, а? Просто я в отпуске. Кстати, SergAntDnepr, Вы с Украины? Вот как раз у Вас и отдыхаю. Крым, Николаевка, пансионат Лучезарный – просто супер!!!
Формирую аккордеон на основе данных из БД. Один раз это 3 закладки, другой раз – 5 и т.д. Вопрос: как «красиво» сделать аккордеон с переменным количеством закладок?
Vitaly, см. предыдущее сообщение
Вот нарыл! Для Всех кого интересует горизонтальный аккордеон
http://flowplayer.org/tools/demos/tabs/accordion-horizontal.html
Gennady, приятного отдыха! Ваш сайт у меня в закладках! Сейчас делаю новый сайт полностью на jQuery. У Вас нашел уйму материала! Спасибо!
Геннадий, подскажите, пожалуйста, как сделать, чтобы по клику на какой-нибудь блок сайта открывался нужный блок виджета
См. методы виджета. В частности метод activate – он поможет программно открывать секции по какому-либо событию. Пример в статье есть, правда для других методов, но это непринципиально.
Уже замучился…. Подскажите пожалуйста как динамически добавить элемент в accordion, что бы он нормально отображался.
Просто добавить я знаю, как. Но когда добавляю элемент он не применяется. Деинициализация и инициализация позже не помогают.
P.S. Мне нужно сделать accordion который можно редактировать. Удалять и добавлять элементы.
Спасибо.
У Вас проблема в следующем: Вы применяете функциональность виджета к некоторой HTML-разметке при загрузке страницы. После этого Вы добавляете еще какую-либо секцию, но к ней-то функциональность аккордеона уже отношения не имеет, поскольку секция добавлена после того, как был инициализирован виджет.
Вероятно Вам может помочь метод bind( type, [data], fn ), который может привязывать к элементам не только стандартные события, но и пользовательские. Попробуйте.
Вот только как применить это я что то вообще не понял. Нашёл описание к методу:
Связывает обработчик с одним или более событиями (например click) для каждого элемента набора. Может также связывать пользовательские события. Возможные события: blur, focus, load, resize, scroll, unload, click, dblclick, mousedown, mouseup, mousemove, mouseover, mouseout, mouseenter, mouseleave, change, select, submit, keydown, keypress, keyup, error. Обработчик события принимает объект событие, что делает возможным предотвращение поведения по умолчанию. Чтобы предотвратить и поведение по умолчанию и «всплывание» события (т.е. передачу события от одного элемента другому), обработчик должен возвращать false.
Всё равно не понял.
Ну ведь как то делают динамически изменяемые элементы. accordion не в какую.
…Ну ведь как то делают динамически изменяемые элементы…
Делают конечно. Я написал, почему у Вас не получается, в принципе показал в какую сторону копать…
Ну, вот на простом примере: есть у Вас скажем пара элементов p и на них повешен обработчик клика. Потом Вы добавляете на страницу еще один p (неважно как именно). Для него обработчик клика не будет действовать… А чтобы заставить его работать надо принять кое-какие меры.
В принципе Вы можете почитать пару статей, думаю, они многое прояснят для Вас:
Обработка событий для элементов DOM, загружаемых через ajax
Плагин Live Query
Спасибо большое! Стало ясно. Пойду читать)))
Стало всё понятно после: Обработка событий для элементов DOM, загружаемых через ajax.
Объясните подробнее про флаг navigation, где ссылка должна находиться? Как сделать меню на основе аккордеона? Можно ли сделать не раскрываемые хидеры без контента и без иконки, при клике на котором сработает ссылка?
Знаете, если немного потерпите, я пожалуй дам отдельную статью про то, как на основе аккордеона построить меню. В комментарии, в двух словах четко и ясно вряд ли получится все объяснить, а в статье, с примерами, думаю будет лучше…
Буду с нетерпением ждать эту статью =).
Закругление уголков.
Здравствуйте, я решил закруглить угалки на этом меню (с помощью jquery.corner) но у меня получаются только нижние углы закруглённые…а мну хотелось бы всё или хотябы только нижние или только верхние…а воплотить не получается.
и ещё я заметил, что при добавление id=»div01″ из 4 имещихся читает только первый сверху…. а остальные не воспроизводятся.
Стас, а у Вас что, все 4 id одинаковые что ли? Просто это почему-то настолько распространенная ошибка… id – это идентификатор, он по определению обязан быть уникальным в пределах веб-страницы. А если их 4 штуки, то вполне естественно, что у Вас отрабатывает только первый.
http://dump.ru/file/3388847
Вот скрипт котрый я пользую…
раньше конечно меню было как в сстандартном файле через но нужно было вписать ссылки поэтому перешёл на и … как то приписал туда див можете помочь, точнее исправить.
через (div)*
потом перешёл (li) (ul)**
Статью Как использовать виджет Accordion в качестве меню? не читали? Там решение…. Про одинаковые id я Вам уже писал парой комментов выше.
Кстати, Вы для начала попробуйте инициализировать виджет с одной-единственной опцией – navigation: true, а потом добавляйте следующие, по одной. Думаю, что изначально заработает, но где-то я встречал вариант с конфликтом. Вроде бы autoHeight: false мешается….
Да, и конечно стоит убрать кусок кода, где работаем с cookie – он же в Вашем варианте не нужен совсем.
Спасибо за статью. Но остался один вопрос. Каким образом можно извлечь индекс активной секции, как в Tabs, например, .tabs(‘option’, ’selected’)?
Вопрос конечно интересный…. Сначала подумал, что легко – а вот и нет…
Есть метод .accordion(«option», optionName, [value]) с помощью которого можно получить/установить значение любой опции.
Конечно я попробовал:
var active = $(‘#accordion’).accordion(‘option’, ‘active’);
так он возвращает значение установленное в опциях при инициализации или null, если опция active не устанавливалась. Можно открывать секции «руками» или программно – значение active не меняется.
Собственно его, это значение изменить то можно, с помощью того же .accordion(«option», optionName, [value]), но смысла в этом никакого…
Пока задал этот вопрос в дискуссиях по UI jQuery….
Спасибо, Геннадий. Этот вопрос можно было сформулировать иначе. Каким образом сохранить активность N-ой секции при PostBack страницы.
Судя по всему с помощью .accordion(«activate» , index), но как получить index?
Так может Вам воспользоваться этим: Как использовать виджет Accordion в качестве меню? Хотя… Ну, в любом случае, посмотрите, если не видели еще…
Да, это работает, но только при PostBack и при Redirect на текущую страицу. У меня Accordion расположен на MsterPage и если в браузере отображается страница, отличная от той, на которой была активизирована секция, этот метод почему-то не работает. А вот .accordion(”activate” , index) срабатывает всегда чётко и даже красиво.
Но в любом случае, большое спасибо.
Ничего лучше пока не придумал, но вроде работает.
<a href=»#»>Section 1</a>
Section 1 content
<a href=»#»>Section 2</a>
Section 2 content
<a href=»#»>Section 3</a>
Section 3 content
$(document).ready(function() {
$(‘#accordion’).bind(‘accordionchange’, function(event, ui) {
$.cookie(«openItem», ui.newHeader.context.all[1].getAttribute(«_tabindex»))
});
});
$(«#accordion»).accordion(‘activate’,parseInt($.cookie(«openItem»)));
Прошу прощения. Но там понятно. На каждый заголовок a href=»#» вешаем аттрибут _tabindex = 0,1,2…
Подскажите как присвоить уникальный URL к каждой закладке
По умолчанию у всех – domain.com/page#
Как сделать например
domain.com/page#1
domain.com/page#2
domain.com/page#3
или что то подобное
Чтобы открывалась нужная закладка при переходе по ссылке
Читайте тут:
Как использовать виджет Accordion в качестве меню?
Геннадий, спасибо за статью.
Не понял только по поводу анимации.
В моем понимании – это автоматическая последовательная смена показа вкладок. Здесь же я не вижу вообще какой-либо анимации.
И возможно ли организовать в Accordion подобие слайдшоу?
Пожалуйста
Анимация здесь – это изменение значения какого-либо параметра (обычно css-свойства) в течение некоторого времени. Так что это растяжимое понятие.
А смену секций организовать можно конечно – используйте метод activate, ну а цикличность смены задавать таймером например….
З.Ы. Я так понимаю – вопрос навеян методом rotate виджета Tabs…
Gennady немогу понять не сильно разбираюсь, подскажите что нужно вписать в скрипт чтобы каждая вкладка (заголовок в теге ) имела постоянный URL и открывалась при переходе по этому URL
На Accordion у меня FAQ, присвоить постоянные URL мне нужно для того чтобы на других страницах сайта я мог ставить ссылку на определенный пункт FAQ
Заголовки – для открытия соответствующей секции, а для того, чтобы реализовать что-то похожее, на то, что Вы хотите – см. статью Как использовать виджет Accordion в качестве меню?
Ничего не получается, я уже пытался сделать как сказано в этой статье «использовать виджет Accordion в качестве меню». У меня FAQ на Accordion работает отлично, за это Вам большое спасибо! но прилинковать неполучается.
У меня wordpress я дописал в шаблон (header.php)
соответственно записал скрипт в папку js
потом в нужную мне страницу я через админку wordpress в html редакторе
вставляю
$(function(){
$(«#accordion»).accordion({
navigation: true,
autoHeight: false,
});
$(«#accordion li a»).click(function(){
$.cookie(«openItem», $(this).attr(«href»));
});
$(«#accordion li a[href$=`" + $.cookie("openItem") + "`]«).addClass(«open»);
});
<a href=»?1-1″>Вопрос 1</a>
Ответ1
<a href=»?1-2″>Вопрос 2</a>
Ответ 2
<a href=»?1-3″>Вопрос 3</a>
Ответ3
После чего аккордеон у мене вообще пропал, получается просто, заголовок текст, заголовок тест…. ссылки вроде есть, но проверить работают ли они невозможно ….
Помогите, что нужно исправить чтоб заработал аккордеон и присвоить к заголовка ссылки, чтоб нужная вкладка могла открываться при переходе по ссылке с другой страницы
LTYBC, скиньте мне свой e-mail через форму тут, а я Вам скину код и дам ссылку на посмотреть код в работе. Просто у меня есть в рабочем состоянии то, что надо Вам.
Спасибо, отправил
Установил аккордеон, но добиться полной функциональности не смог: на отдельной html-странице все работает, но как только пытаешься использовать его внутри новости блога, то все перестает работать: никакого аккордеона, просто заголовок, текст и т. д.
Перепробовал кучу вариантов: функциональность привязывал и через хедер и непосредственно через html-редактор новости в админке.
Проверил пути до css – он их видит. Подскажите куда копать дальше?
Спасибо.
Ну, например, поставить себе FireBug – это такой плагин к FF, и значительно облегчить себе жизнь. Он Вам все покажет и расскажет, в каком месте у Вас ошибка.
FireBug при анализе элементов:
Section 1
и прочее..
в упор не видит jquery-ui-1.7.2.custom.css (только style.css), хотя при просмотре исходного кода всей страницы я вижу этот css в хедере и спокойно могу перейти по этой ссылке, чтобы посмотреть его.
Nikolay, Вы консоль посмотрите, нет ли там ошибки вроде того, что $ is not defined?
Если есть – смотрите пути к библиотеке внимательно. Особенно, если у Вас движок какой-либо.
Мужики, я недопонял, как прописать, чтоб при открыии сайта аккордеон был закрыт, а то первое окошко открыто получаетя…
Нужно передать пару опций:
active: false,
collapsible: true
Я так понимаю, виджет должен быть кроссбраузерным, но у себя не получил нигде кроме Файрфокса – ие6, опера 9-10 никак не реагируют. ни стилей ни яваскрипта ((
В частности, ошибка в Опере:
Event thread: DOMContentLoaded
Error:
name: TypeError
message: Statement on line 4: Type mismatch (usually non-object value supplied where object required)
stacktrace: n/a; see opera:config#UserPrefs|Exceptions Have Stacktrace
и еще куча ошибок css такого вида:
Linked-in stylesheet
Declaration syntax error
Line 76:
i-widget-content .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70);
Как с этим бороться?
Поствил аккордеон вот сюда http://zakazstankam.ru/
(буквально в эту субботу 24 окт.)
И в Опере и в эксплорере всё работает хорошо.
Дома, на локальном сервере, делаю сайт, где аккордеон будет в качестве менюшки. Пока проблем не возникает тоже. Делаю на движке PHP Fusion.
Единственно – при прописывании HTML кода аккордиона, меняю кавычки такого типа » на одинарные ‘.
Например: было
прописываю
To Grey: виджет и есть кроссбраузерный. Есть демо, смотрите под разными браузерами. Работает… А почему у Вас ошибки возникают – тут тяжело сказать. Пробуйте идти от простого к сложному. Начните с испытания самого простого примера.
приделал я к IPB модульчик и там заюзал 2 виджа dialog и accordion… Но не просто по отдельности, а совместил, плюс ещё задействовал ajax… Короче…
В видж диалог с помощью .load подгружаю некий html код отформаченый в соответствии с требованиями аккордиона. непосредственно перед тем как загрузить html в диалог делаю $(«#dialog»).accordion( «destroy» );(аккордион при начальной загрузке странички тоже инициализируется), а после загрузки $(document).ready(function(){$(«#dialog»).accordion()});
Эффект следующий: видно что промаргивает правильный вид аккордиона, но потом форматирование тут же сваливается на инвижнское… Я так понимаю что тут что-то с CSS-ми связано. Как-нить это лечится?
PS: Пардон за корявость изложения…
Хм. Похоже не в css дело… Отключил всё инвижнское, оставил только свой код… Видимо где-то засада со связкой виджетов, только непонятно где
Мда. Решил проблему собрав всё в одну команду
$(«#dialog»).load(«blablabla.html», function(){$(«#dialog»).accordion(«destroy»); $(«#dialog»).accordion({ header: «h3″ })});
Если решение тривиальное и напрашивалось само, не обессудьте, я в javaScript не сильно долго вожусь… А JQurey только вчера для себя открыл
Обсуждение статьи можно продолжить на форуме jQuery.