jQuery: Сворачиваемые блоки

Небольшой пример демонстрирующий эффект сворачивания однотипных блоков (например постов в блоге или виджетов в сайдбаре) с помощью jQuery.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<div class="post">
    <div class="title">
        <h3><a href="" title="">Заголовок</a></h3>
        <p>Автор, 12.02.2010</p>
    </div>
    <div class="entry">
        <!-- Контент -->
    </div>
</div>
 
<div class="post">
    <div class="title">
        <h3><a href="" title="">Заголовок</a></h3>
        <p>Автор, 12.02.2010</p>
    </div>
    <div class="entry">
        <!-- Контент -->
    </div>
</div>
 
…

В данном примере присутствуют несколько постов. Сворачиваться будет их содержимое.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
.post {
    padding:10px 20px;
    position:relative;
    background:#eee;
    margin-bottom:20px
}
.inactive {
    color:#bbb
}
.post .title {
    position:relative;
    height:1%
}
.post .title h3 {
    font-size:1.4em
}
.post .title h3 a {
    text-decoration:none;
    color:#000
}
.inactive .title h3 a {
    color:#bbb
}
.post .title p {
    font-size:0.7em;
    font-style:italic;
    font-weight:bold;
    margin:0
}
.post .title span {
    position:absolute;
    right:0;
    top:30%;
    cursor:pointer;
    width:14px;
    height:14px;
    background:url(trigger.gif) no-repeat left bottom;
    display:block;
    font-size:0
}
#content .inactive .title span {
    background-position:left top
}
#content .post .entry {
    padding:10px 0
}

Span служит кнопкой для сворачивания и разворачивания блоков и добавляется с помощью js. Поэтому пользователи с отключенным js его не увидят.

1
2
3
4
5
6
7
8
9
$('.title').append('<span></span>');
$('.post span').each(function() {
   var trigger = $(this), state = false, el = trigger.parent().next('.entry');
   trigger.click(function(){
      state = !state;
      el.slideToggle();
      trigger.parent().parent().toggleClass('inactive');
   });
});

Обсуждение:

  1. Русский кодер

    Интересно. Сохранил в закладках. Как раз хотел подобное в админке сделать на одном проекте.

  2. Владимир

    Спасибо за код. Какраз ищу что-то похожее для нового сайта. Аккордеон там не подходит ибо нужна возможность открывать несколько блоков одновременно.

    Вопрос. Кто-то может пояснить эту строчку:
    var trigger = $(this), state = false, el = trigger.parent().next(‘.entry’);

    • Alex

      Это объявление переменных.

  3. ApxuMeD

    А как сделать, чтобы блоки были изначально закрыты?

    • Alex

      Добавьте $('.entry').hide(); или с помощью css скрывайте.

      • Лиля

        А можно чуть подробнее? Куда что добавлять, чтобы изначально всё было свёрнуто?
        Помогите, пожалуйста!

  4. роман

    если свернуть 2 и более блоков, потом нажать развернуть, разворачиваются все!, это можно исправить?

    • Alex

      Что-то я подобного поведения не заметил. В каком это браузере?

        • Alex

          Проверял, дожно всё работать.

          • mihdan

            Неа. Google Chrome сборка 4,0,249 (ОС Linux)

          • Alex

            Та же сборка, но на WIn 7.

          • mihdan

            См. ответ Владимиру

    • Владимир

      Хром 5.0.307.7 полет нормальный.
      Под «разворачивается все» возможно имеется ввиду не работа скрипта, а перегрузка страницы — в начальном варианте все блоки какраз развернуты

      • mihdan

        Имелось ввиду не клик по плюсику, а:

        Заходим в пример, сворачиваем первый и второй блок, нажимаем на заголовок первого — разворачиваются оба — сделать разворот блока при клике на заголовок.

        При клике на плюсик — все работает как надо: разворачивается именно тот блок.

        • Alex

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

  5. роман

    да действительно, опера все нормально, «недостаток» наблюдал через IE8

    • Alex

      В IE8 также проверял, всё нормально.

      Если кто-нибудь еще отпишет, то будем смотреть.

      • роман

        странно, щас попросил товарищей проверить, у всех работает корректно, проверил сам тоже корректно … ушел думать )

  6. ApxuMeD

    протестил в ИЕ8, все ок

  7. Владимир

    Вынес сворачивание в отдельную функцию:

    function toggleBlock(el){
    el.slideToggle();
    el.parent().toggleClass('inactive');
    }

    Теперь можно использовать так:

    $(document).ready(function() {
    $('.title').append('');
    $('.post span').each(function() {
    var trigger = $(this);
    var el = trigger.parent().next('.entry');
    var title = trigger.parent().find('h3');
    //Клик по плюсу
    trigger.click(function(){
    toggleBlock(el);
    });
    //Клик по заголовку
    title.click(function(){
    toggleBlock(el);
    return false;
    });
    });
    //Свернуть первый блок
    toggleBlock($('.entry').eq(0));
    });

    • 2007

      В IE8:

      Webpage error details
      Message: Object expected
      Line: 18
      Char: 1
      Code: 0
      URI: file:////…/script_.js

  8. asse

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

  9. asse

    кто-нибудь может приветси код, как правильно внедрить этот плагин jquery.cookie в данный скрипт? заранее спасибо большое!

    • mihdan

      Для начала попробуйте сами, покажите что получилось, тогда поможем

      • asse

        к сожалению, я в яваскрипте не силен =(

  10. petrik

    Классный скрипт, будет эму применение !
    Спс !

  11. Baiker

    Спасибо за скрипт! радует, что прост в установке :) приткнул в один свой проектик :)

  12. Win Man

    Спасибо за отличную ссылку. Сильно не хватает «Свернуть/развернуть все».

  13. pder

    даже в IE все нормально. Огромное спасибо, ретвитнул!!

  14. yavasilek

    А как куки прикрутить? Просто я немного по другому это сделал с куками, но в IE не пашет((

    • Alex

      Проверил только что, всё нормально.

  15. cyberacing

    добрый день!
    использовал данный код на одном из своих сайтов. вставил все как описано, в итоге получился один неприятный глюк. при развороте блока в FF низ блока подпрыгивает после разворота, а в ИЕ подпрыгивает блок при сворачивании (становится ближе к вышестоящему). в Сафари и Хром все нормально вроде (по крайней мере визуально этих подпрыгиваний не видно). с чем это может быть связано, не подскажете?

    • Сергей

      У меня такая проблема возникла из-за неправильного задания высоты блока.
      Изменил высоту и всё стало ок.

      $(‘#slider2′).anythingSlider({
      width : 600,
      height : 350

  16. 2007

    Доброго времени суток.
    Покажите, пожалуйста, как прописать установки по-умолчанию. Я имею ввиду все открытые блоки, всё закрыть или какойто один раскрывать…
    Спасибо.

  17. Garry

    А как добавить скрытие по клику не только на картинке справа, но и на заголовке записи? Чтобы клик на заголовке не вел на страницу записи, а сворачивал блок…

    • Alex

      Попробуйте так:
      $('.title').append('');
      $('.post span, .post h3').each(function() {
      var trigger = $(this), state = false, el = trigger.parent().next('.entry');
      trigger.click(function(){
      state = !state;
      el.slideToggle();
      trigger.parent().parent().toggleClass('inactive');
      return false;
      });
      });

      • Garry

        Картинка справа пропала. Хотелось бы, чтобы она осталась и менялась синхронно с заголовком. И чтобы сворачивание работало и на ней.

        • Alex

          Не должна пропасть, проверяйте всё ли правильно сделали.

          • Garry

            Спасибо. Всё получилось. А вместо одной картинки как две прописать?

          • Alex

            В каком смысле две?

  18. Garry

    Сейчас, например, плюс и минут сохранены в одной гифке. А если заменить их на какие-то другие, и не хочу сохранять в один файл, а например, использовать expand.png и collapse.png?

    • Alex

      Всё оформление через css. Пропишите у селектора#content .inactive .title span другое фоновое изображение и всё.

  19. Рустам

    Спасибо за статью. Пригодилось.
    Но нужно еще реализовать возможность раскрытия блока по наведению мышкой на блок(hover). И сворачивание обратно. Делаю меню. Помогите пожалуйста, что в скрипте дописать…

    • Alex

      В css у .post .title span вместо right:0 используйте нужное значение left.

  20. Юджин

    Подскажите плиз как сделать так что бы при открытом 1 блоке мы открывали 2 блок и при этом первый блок закрывался. Тоесть что бы максимум был открыт 1 блок. Это было бы удобно. А то если много блоков с большим количеством информации сайт должен быть очень длиным и при закрытых блоках пустым. А так можно его сделать коротким и открывать один блок за другим. Ну разумееться при изначально закрытых блоках.

  21. Юджин

    А лучше подскажите какая функция позволяет делать общий блок резиновым.

    • Alex

      По умолчанию блоки резиновые, никаких функций не нужно.

  22. Юджин

    Столько много вопросов и проблем =)
    Еещ 1. На примере при сворачивании и разворачивании меняться триггер на + и -. Так вот у меня всегда — Горит. Как изменить?

    • Alex

      При нажатии, кнопке добавляется класс inactive, который меняет позиционирование фона.

  23. Юджин

    Тоесть вотэтот:
    #content .inactive .title span {
    background-position:left top}
    Не понятно 2 вещи.
    1 После бэкграунды не стоит точки с запятой=)
    2 У меня изначально блоки закрыты поэтому тут у меня стоит «top» :
    .post .title span {
    position:absolute;
    right:0;
    top:30%;
    cursor:pointer;
    width:14px;
    height:14px;
    background:url(«trigger.gif») no-repeat scroll left top transparent;
    display:block;
    font-size:0
    А тут я поставил:
    #content .inactive .title span {
    background-position:left bottom}
    Но к сожалению ничего не меняеться.
    Изначально функция как бут-то не работает. В примере работает, у меня нет.

    • Alex

      Внимательно сравните с примером, видно где-то ошибка у вас.

  24. Я

    Этот сайт классно выглядит в IE АТАС!!!!

    • Alex

      Спасибо, я в курсе. В прошлые выходные решил переверстать шаблон на html5, до ie пока руки не дошли. Скоро поправлю.

  25. AiR

    Есть ли возможность прикрутить кнопку раскрыть всё / спрятать всё? оч нужно, скрипт прикруутил, а вот кнопку сделать которую затребовали не могу.

    • ermak00

      Да такая же проблема. заказали кнопочку которая открывает все вкладки сразу
      по дефолту они закрыты (по закрытие прочитал тут, как это сделать)

      вот что получилось…все работает норм
      $(document).ready(function() {
      $(‘.entry’).hide();
      $(‘.title’).append(»);
      $(‘.post span, .post h3′).each(function() {
      var trigger = $(this), state = false, el = trigger.parent().next(‘.entry’);
      trigger.click(function(){
      state = !state;
      el.slideToggle();
      trigger.parent().parent().toggleClass(‘inactive’);
      return false;
      });
      });

      });

  26. Михаил

    Спасибо за статью,но появилось одно но!
    Куда вставлять Javascript ?
    А то видны только простые блоги,которые вообще не пашут!

  27. Павел

    У меня вопрос ,как зделать чтоб когда откриваеш один сворачивается второй?

    • Виталий

      $(function() {
      $(‘.title’).append(»);
      $(«.post span»).parent().next(‘.entry’).hide();
      $(«.post span»).parent().parent().addClass(‘inactive’);
      $(«.post span»).click(
      function(){
      if($(this).parent().parent().hasClass(‘inactive’))
      {
      $(«.post span»).parent().next(‘.entry’).hide();
      $(«.post span»).parent().parent().addClass(‘inactive’);
      $(this).parent().next(‘.entry’).show(‘slow’);
      $(this).parent().parent().removeClass(‘inactive’);
      }
      else
      {
      $(this).parent().next(‘.entry’).hide(‘slow’);
      $(this).parent().parent().addClass(‘inactive’);
      $(«.post span»).parent().next(‘.entry’).hide();
      $(«.post span»).parent().parent().addClass(‘inactive’);
      }
      });
      });

      Вроде работает, но мож кто знает решение получше

  28. Виталий

    А зачем в скрипте нужна переменная state?
    Сделал без нее и вроде ничего не меняется

    $(function() {
    $(‘.title’).append(»);
    $(«.post span»).click(
    function(){
    $(this).parent().next(‘.entry’).toggle(‘slow’);
    $(this).parent().parent().toggleClass(‘inactive’);
    });
    });

  29. Виталий


    $(function() {
    $('.title').append('');
    $(".post span").click(
    function(){
    $(this).parent().next('.entry').toggle('slow');
    $(this).parent().parent().toggleClass('inactive');
    });
    });

  30. Виталий

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

  31. ermak00

    Помогите плиз сделать кнопочку, при нажатии на которую, все вкладки раскрываются :(

  32. Виталий

    Создаешь кнопку с id=»Btn1″ и добавляешь в код


    $('#Btn1').click(function(){
    $('.entry').show().parent().removeClass('inactive');
    });

  33. Andrey

    А есть плагин для WordPress который это сам делает?

  34. Андрей

    Спасибо!
    Очень помогло!

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*