5 285 Скрипты / Accordion

Гибкий аккордеон


Создадим простой быстрореагирующий аккордеон, который при раскрытии будет перемещаться к верхней области просмотра. Также будет добавлено несколько переходов CSS3 для стрелки. Гибкость заключается в том, что ширина аккордеона будет подстраиваться под размеры экрана.

HTML

Cтруктура html будет состоять из контейнера с ID и class "st-accordion" и неупорядоченного списка. У элементов списка будет ссылка, служащая заголовком пункта аккордеона и блок с контентом, который изначально скрыт. Блок SPAN с классом "st-arrow" будет стрелкой в правой части, которая появляется при наведении на название пункта:

<div id="st-accordion" class="st-accordion">
    <ul>
        <li>
            <a href="#">Название пункта<span class="st-arrow">Открыть или Закрыть</span></a>
            <div class="st-content">
                <p>Контент</p>
            </div>
        </li>
        <li>
              ...
        </li>
    </ul>
</div>

CSS

В начале стилизуем основной контейнер, дав ему ширину в 100%, так как хотим, чтобы он подстраивался под ширинув внешнего контейнера. Если внешнего контейнера у вас нет, то используйте значение в процентах, которое вам больше подходит. В нашем примере у внешнего контейнера максимальная ширина 800px, а ширина 90%. У "st-accordion" будет минимальная ширина 270px:

.st-accordion{
    width:100%;
    min-width:270px;
    margin: 0 auto;
}

Предположим, хотя в примере он и используется, у нас есть некоторый стиль reset.css, который сбрасывает значения padding и margin из списков UL и т. д., тогда мы определяем стиль для каждого элемента списка. Установим начальную высоту 100px, в основном она будет высотой элемента ссылки, а переполнение - overflow - будет скрыто, т.е. контент мы не увидим. При открытии элемента, мы анимируем его высоту, чтобы показать контент. Границы border позволяет нам создать разделение между пунктами аккордеона:

.st-accordion ul li{
    height: 100px;
    border-bottom: 1px solid #c7deef;
    border-top:1px solid #fff;
    overflow: hidden;
}
У первого пункта не будет верхней границы:
.st-accordion ul li:first-child{
    border-top:none;
}
Для ссылок добавим цветной переход при наведении мышки. Высота строки - line-height - должна быть такой же, как и начальная высота элемента списка:
.st-accordion ul li > a{
    font-family: Verdana,Georgia, serif;
    text-shadow: 1px 1px 1px #fff;
    font-size: 46px;
    display: block;
    position: relative;
    line-height: 100px;
    outline:none;
    -webkit-transition:  color 0.2s ease-in-out;
    -moz-transition:  color 0.2s ease-in-out;
    -o-transition:  color 0.2s ease-in-out;
    -ms-transition:  color 0.2s ease-in-out;
    transition:  color 0.2s ease-in-out;
}
.st-accordion ul li > a:hover{
    color: #1693eb;
}
SPAN для стрелки будет расположен абсолютно, мы также скроем его, поместив за пределами элемента ссылки с прозрачностью 0. С помощью переходов стрелка будет появляться с правой стороны:
.st-accordion ul li > a span{
    background: transparent url(../images/down.png) no-repeat center center;
    text-indent:-9000px;
    width: 26px;
    height: 14px;
    position: absolute;
    top: 50%;
    right: -26px;
    margin-top: -7px;
    opacity:0;
    -webkit-transition:  all 0.2s ease-in-out;
    -moz-transition:  all 0.2s ease-in-out;
    -o-transition:  all 0.2s ease-in-out;
    -ms-transition:  all 0.2s ease-in-out;
    transition:  all 0.2s ease-in-out;
}
.st-accordion ul li > a:hover span{
    opacity:1;
    right: 10px;
}
Когда мы раскроем пункт аккордеона, то назначим для него класс st-open и ссылка останется с цветом, какой был при наведении. SPAN будет повернут на 180 градусов:
.st-accordion ul li.st-open > a{
    color: #1693eb;
}
.st-accordion ul li.st-open > a span{
    -webkit-transform:rotate(180deg);
    -moz-transform:rotate(180deg);
    transform:rotate(180deg);
    right:10px;
    opacity:1;
}
Это стиль контента и его элементов:
.st-content{
    padding: 5px 0px 30px 0px;
}
.st-content p{
    font-size:  16px;
    font-family:  Georgia, serif;
    font-style: italic;
    line-height:  28px;
    padding: 0px 4px 15px 4px; 
}
.st-content img{
    border-right:1px solid #fff;
    border-bottom:1px solid #fff;
}
С помощью media запроса, удостоверимся, что размер шрифта заголовка будет меньше:
@media screen and (max-width: 320px){
    .st-accordion ul li > a{
        font-size:36px;
    }
}

JS

Подключаем jQuery библиотеку и плагин easing и плагин accordion, о котором ниже чуть подробнее.

Самые важные части плагина accordion.

Начнем с настроек по умолчанию:

$.Accordion.defaults = {
  // Открыт или Закрыт пункт. -1 означает, что все пункты свернуты по умолчанию.
  open: -1,
  // если установлено true, то только один элемент может быть раскрыт, другой, если был открыт, свернется.
  oneOpenedItem: false,
  // сокрость анимации открытия / закрытия
  speed: 600,
  // название используемой анимации открытия / закрытия
  easing: 'easeInOutExpo',
  // сокрость анимации прокрутки
  scrollSpeed: 900,
  // анимация при прокрутке
  scrollEasing: 'easeInOutExpo'
};
Инициализируем плагин вызывая функцию _init:
_init: function(options) {
  this.options = $.extend(true, {}, $.Accordion.defaults, options);
  // проверка опций
  this._validate();
  // current is the index of the opened item
  this.current = this.options.open;
  // скрыть содержимое
  this.$items.find('div.st-content').hide();
  // сохранить оригинальную высоту и значение top каждого пункта
  this._saveDimValues();
  // если мы хотим, пункт открыт по умолчанию...
  if (this.current != -1)
    this._toggleItem(this.$items.eq(this.current));
  // инициализируем события
  this._initEvents();
},

Функция _saveDimValues сохраняет исходную высоту и значение top элемента так, чтобы мы знали до куда должны прокрутить при открытии элмента.
Если мы установили по умолчанию элемент открытым, то вызывается функция _toggleItem. Затем инициализируем событие.
Функция _toggleItem заботится о двух случаях, когда мы кликаем по пунктам, то есть при открытии и закрытии элементов. И затем прокручиваем окно до положения при котором элемент по которому кликаем, останется вверху за счет функции _scroll:
_toggleItem: function($item) {
  var $content = $item.find('div.st-content');
  ($item.hasClass('st-open'))
  ?
  (this.current = -1, $content.stop(true, true).fadeOut(this.options.speed), $item.removeClass('st-open').stop().animate({
    height: $item.data('originalHeight')
  }, this.options.speed, this.options.easing))
  :
  (this.current = $item.index(), $content.stop(true, true).fadeIn(this.options.speed), $item.addClass('st-open').stop().animate({
    height: $item.data('originalHeight') + $content.outerHeight(true)
  }, this.options.speed, this.options.easing), this._scroll(this))
},
В функции _initevents мы инициализируем два события, нажатие на пункт и изменение размеров окна. Когда мы кликаем по элементу мы или открываем или закрываем его, вызывая функцию _toggleItem и если мы установили опцию oneOpenedItem в значение true, то мы закрываем сначала любой открытый элемент прежде, чем открыть текущий.
Когда окно изменено, мы должны сбросить исходные значения элемента и высоту контента. И затем элемент прокручивается к верху:
_initEvents: function() {
  var instance = this;
  // открыть / закрыть пункт
  this.$items.find('a:first').bind('click.accordion', function(event) {
    var $item = $(this).parent();
    // закрыть открытый пункт, если oneOpenedItem - true
    if (instance.options.oneOpenedItem && instance._isOpened() && instance.current !== $item.index()) {
      instance._toggleItem(instance.$items.eq(instance.current));
    }
    // открыть / закрыть пункт
    instance._toggleItem($item);
    return false;
  });
  $(window).bind('smartresize.accordion', function(event) {
    // сбросить исходные значения
    instance._saveDimValues();
    // сбросить высоту контента любого элемента, который в настоящий момент открыт
    instance.$el.find('li.st-open').each(function() {
      var $this = $(this);
      $this.css('height', $this.data('originalHeight') + $this.find('div.st-content').outerHeight(true));
    });
    // прокуртка до текушего
    if (instance._isOpened())
      instance._scroll();
  });
},
Это наиболее важные функции для данного аккордеона.
Скачать 1415Загрузок 56,2 Kb
Демо

Комментарии

  • Facebook
  • Вконтакте

Похожие статьи