Парочка аккордеонов

Vladimir
Опубликовано в: CSS, JavaScript

Недавно в одном из проектов появилась необходимость использовать аккордеон (подобный используемому на Desert Ridge Marketplace). Любят заказчики дешевые эффекты, ничего здесь не поделаешь :-)

Чем мне не понравился аккордеон на Desert Ridge — это полной зависимостью от JavaScript: если JavaScript выключен, навигация по сайту переставала работать. Это мне не понравилось, и я решил написать свой.

Представляю два решения:

  1. Подменю сворачивается/разворачивается по щелчку, элементы меню не зависят друг от друга;
  2. Подменю сворачивается/разворачивается по щелчку, при этом не может быть более одного развёрнутого подменю.

При выключенном JavaScript оба аккордеона трансформируются в двухуровневый список.

Поехали. Будем использовать следующую разметку:

[-]
View Code HTML
    <ul id="accordion">
        <li>
            <a href="#">Item 1</a>
            <ul>
                <li><a href="#">SubItem 1.1</a></li>
                <li><a href="#">SubItem 1.2</a></li>
                <li><a href="#">SubItem 1.3</a></li>
                <li><a href="#">SubItem 1.4</a></li>
            </ul>
        </li>

        <li class="active">
            <a href="#">Item 2</a>
            <ul>
                <li><a href="#">SubItem 2.1</a></li>
                <li><a href="#">SubItem 2.2</a></li>
                <li><a href="#">SubItem 2.3</a></li>
                <li><a href="#">SubItem 2.4</a></li>
            </ul>
        </li>

        <li>
            <a href="#">Item 3</a>
            <ul>
                <li><a href="#">SubItem 3.1</a></li>
                <li><a href="#">SubItem 3.2</a></li>
            </ul>
        </li>

        <li>
            <a href="#">Item 4</a>
            <ul>
                <li><a href="#">SubItem 4.1</a></li>
                <li><a href="#">SubItem 4.2</a></li>
            </ul>
        </li>
    </ul>

С разметкой всё просто: обычный двухуровневый список; предполагается, что меню Item2 активно (то есть должно быть развёрнуто).

Оформим аккордеон при помощи CSS:

[-]
View Code CSS
a { text-decoration: none; color: #00F; }
a:hover { text-decoration: underline; }
#accordion a { outline: 0; }
   
#accordion, #accordion ul, #accordion li {
    list-style: none;
    margin: 0;
    padding: 0;
    display: block;
}

#accordion {
    border: 1px solid #CCC;
    width: 150px;
}

#accordion ul {
    margin-left: 40px;
}

#accordion > li {
    border-bottom: 1px solid #CCC;
    padding: 2px 5px;
}

#accordion > li:last-child {
    border-bottom: 0;
}

#accordion li.active > a {
    color: red;
}

Покажем уродство IE6, не понимающего CSS 2.1:

[-]
View Code CSS
* html #accordion li {
    border-bottom: 1px solid #CCC;
    padding: 2px 5px;
}

* html #accordion li li {
    border-bottom: 0;
    padding: 0;
}

* html #accordion {
    border-bottom: 0;
}

* html #accordion li.active a {
    color: red;
}

* html #accordion li.active ul a {
    color: blue;
}

За использование пяти лишних правил я и не люблю IE6 (и это мы еще используем простую разметку).

Переходим к JavaScript. В данных примерах я использую библиотеки Prototype и Scriptaculous Effects (всё очень легко переводится на jQuery).
Вариант 1: независимые элементы меню

[-]
View Code Javascript
$$('#accordion > li:not([class="active"]) ul').invoke('setStyle', { display : 'none' }).invoke('addClassName', 'collapsed');
$$('#accordion > li[class="active"] ul').invoke('addClassName', 'expanded');
$$('#accordion > li > a').invoke('observe', 'click',
    function(e)
    {
        e.stop();
        var ul = e.findElement('a').up('li').down('ul');
        if (ul) {
            new Effect.toggle(ul.toggleClassName('collapsed').toggleClassName('expanded'), 'blind');
        }
    }
);

Рабочий пример для первого варианта.

Вариант 2: развёрнуто не более одного меню

[-]
View Code Javascript
$$('#accordion > li:not([class="active"]) ul').invoke('setStyle', { display : 'none' }).invoke('addClassName', 'collapsed');
$$('#accordion > li[class="active"] ul').invoke('addClassName', 'expanded');
$$('#accordion > li > a').invoke('observe', 'click',
    function(e)
    {
        e.stop();
        var ul = e.findElement('a').up('li').down('ul');
        if (ul) {
            if (ul.hasClassName('collapsed')) {
                var c = $$('#accordion ul:not([class="collapsed"])')[0];
                if (c) {
                    new Effect.BlindUp(c.toggleClassName('collapsed').toggleClassName('expanded'));
                }
            }
            new Effect.BlindDown(ul.toggleClassName('collapsed').toggleClassName('expanded'));
        }
    }
);

Рабочий пример для второго варианта.

Всё очень просто!

Добавить в закладки
  • del.ici.ous
  • Digg
  • Furl
  • Google
  • Simpy
  • Spurl
  • Y! MyWeb
  • БобрДобр
  • Мистер Вонг
  • Yandex.Закладки
  • Текст 2.0
  • News2
  • AddScoop
  • RuSpace
  • RUmarkz
  • Memori
  • Google Bookmarks
  • Писали
  • СМИ 2
  • Моё Место
  • 100 Закладок
  • Ваау!
  • Technorati
  • RuCity
  • LinkStore
  • NewsLand
  • Lopas
  • Закладки - IN.UA
  • Connotea
  • Bibsonomy
  • Trucking Bookmarks
  • Communizm
  • UCA
  • Slashdot
  • Magnolia
  • Blogmarks
  • Current
  • Meneame
  • Oknotizie
  • Diigo
  • Funp
  • Hugg
  • Dealspl.us
  • N4G
  • Mister Wong
  • Faves
  • Yigg
  • Fresqui
  • Care2
  • Kirtsy
  • Sphinn

Связанные записи

13
Апр
2008

Комментарии к статье «Парочка аккордеонов» (6)  »

  1. Vladimir says:

    Забыл сказать: код (для любого из примера) должен находиться внутри функции, вызываемой либо по событию onload, либо (более предпочтительный вариант) по событию DOMContentLoaded.

    С использованием Prototype это будет выглядеть следующим образом:

    [-]
    View Code Javascript
    Event.observe(window, 'load', function() { /* Code goes here */ });

    или

    [-]
    View Code Javascript
    document.observe('dom:loaded', function() { /* Code goes here */ });
  2. Crazy_Serg says:

    на странице
    http://blog.sjinks.org.ua/tag/accordion/
    Вылазит вверху кусок кода
    } elseif(is_search() || is_404()) { ?>

  3. Vladimir says:

    Спасибо, сейчас поправлю — какой-то плагин плохо себя ведёт…

  4. Crazy_Serg says:

    А ты не мог бы связаться, со мной по мылу есть дело

  5. Vladimir says:

    Crazy_Serg, почта по-видимому не доходит, mxs.ukr.net [195.214.192.100] возвращает ошибку 451. Если я правильно понимаю, это greylisting, и следующая попытка доставки будет через 10-12 часов. Если что, пишите мне на vladimir at sjinks dot org dot ua или в ICQ: 290736765.

Подписаться на RSS-ленту комментариев к статье «Парочка аккордеонов» Trackback URL: http://blog.sjinks.org.ua/javascript/91-couple-of-accordions/trackback/

Оставить комментарий к записи «Парочка аккордеонов»

Вы можете использовать данные тэги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Оставляя комментарий, Вы выражаете своё согласие с Правилами комментирования.

Подписаться, не комментируя