Универсальный jQuery-скрипт для блоков с вкладками (табами)

Вступление

Вкладки Мое знакомство с фреймворком jQuery произошло в 2008-м году, после того, как, однажды, на одном из англоязычных сайтов я нашел jQuery-скрипт, который позволяет создавать блоки с удобными вкладками. Этому скрипту я посвятил отдельный пост на данном блоге.

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

Почему я называю свой новый скрипт для jQuery-вкладок универсальным:

  • он позволяет создавать неограниченное количество вкладок в пределах одного блока, при этом нет необходимости нумеровать вкладки с помощью CSS-классов, как это было сделано в старом варианте;
  • можно создать сколько угодно таких блоков с вкладками опять же без необходимости нумеровать эти блоки через CSS-классы;
  • содержимое jQuery-скрипта, реализующего вкладки, остается неизменным (всего 0,3 килобайта), т.е. не разрастается в зависимость от количества блоков или вкладок, как это было в старом варианте, при этом размер нового варианта скрипта не больше размера скрипта для одного блока с вкладками из старого варианта.

Что ж, хватит сухих слов, переходим к сути.

Код jQuery-скрипта для переключаемых блоков с вкладками

Не забывайте в первую очередь подключить сам фреймворк jQuery (если он еще не подключен на вашем сайте), например, так (вставляется между тегами <head> и </head>):

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

Я предпочитаю “брать” его с Гугла, поскольку, во-первых, велика вероятность, что у посетителя, который зайдет на сайт, jQuery уже закэширован в браузере (значит страница загрузится быстрее), во-вторых, скорость серверов Гугла стабильна и быстра, в-третьих, Гугл отдает его в сжатом виде (gzip), и, например, для версии 1.4.2 размер составляет всего 24 килобайта по сравнению с несжатым файлом (70 Кб).

Вот такой у меня получился скрипт:

(function($) {
$(function() {

	$('ul.tabs').each(function() {
		$(this).find('li').each(function(i) {
			$(this).click(function(){
				$(this).addClass('active').siblings().removeClass('active')
					.parents('div.tabs').find('div.tabs__content').eq(i).fadeIn(150).siblings('div.tabs__content').hide();
			});
		});
	});

})
})(jQuery)

Добавлено 07.03.2010 (обновлено 09.04.2015)

В комментариях подсказали еще более сокращенный вариант этого скрипта (обратите внимание, что для него нужно использовать jQuery не ниже версии 1.7):

(function($) {
$(function() {

	$('ul.tabs__caption').on('click', 'li:not(.active)', function() {
		$(this).addClass('active').siblings().removeClass('active')
			.closest('div.tabs').find('div.tabs__content').removeClass('active').eq($(this).index()).addClass('active');
	})

})
})(jQuery)

Для тех, кто еще не знает, как подключать этот скрипт – создать файл с расширением .js, вставить в него код скрипта и подключить по аналогии c jQuery (см. выше), естественно, заменив ссылку на адрес скрипта.

Скачать

Если вы желаете отблагодарить автора финансово, воспользуйтесь следующей формой, указав произвольную сумму рублей:

HTML-код, который нужно использовать для скрипта

<div class="tabs">
	<ul class="tabs__caption">
		<li class="active">1-я вкладка</li>
		<li>2-я вкладка</li>
	</ul>
	<div class="tabs__content active">
		Содержимое первого блока
  </div>
	<div class="tabs__content">
		Содержимое второго блока
  </div>
</div><!-- .tabs -->

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

Обязательные CSS-стили для вышеуказанного HTML-кода

.tabs__content {
	display: none; /* по умолчанию прячем все блоки */
}
.tabs__content.active {
	display: block; /* по умолчанию показываем нужный блок */
}

Если, например, необходимо, чтобы по умолчанию отображался второй блок, тогда нужно переместить класс .active во второй блок div.tabs__content, а также переместить класс .active во второй элемент в списке вкладок.

Примеры

  • 1-й пример.
  • 2-й пример, в котором запоминается активная вкладка после перезагрузки страницы (с помощью cookie).
  • 3-й пример, в котором запоминается активная вкладка после перезагрузки страницы (с помощью localStorage, меньше кода по сравнению с cookie).
  • 4-й пример, в котором при переходе по ссылке с якорем, указывающим на номер таба, активируется соответствующий таб.

P.S. Мне в твиттере как-то сказали, что я “изобретаю колесо”, что такой скрипт уже есть в jQuery UI. Ну и пусть, пусть я “изобрел колесо”, главное, что я получаю большое удовольствие от данного процесса и одновременно повышаю свой опыт в jQuery. Разве это плохо? =)

* * *

Требуется разработка печатного каталога товаров или услуг? Создание каталога в студии «Верстаем.ru» это оптимальное решение!

Комментарии (978)

  1. Михаил
    2 ноября 2016 г. в 12:00

    Дмитрий, спасибо за скрипт.

    Подскажи, пожалуйста, можно ли сделать так, чтобы на первом табе отображалось содержимое всех табов?

    Хочу сделать табы для портфолио по структуре:

    [Все] [Дизайн] [Программирование] [Копирайтинг]

    1. 2 ноября 2016 г. в 13:11 / ответ на коммент Михаил

      Такое скрипт не предусматривает.

  2. Валентин
    27 ноября 2016 г. в 11:53

    Спасибо большое за скрипт! Могли бы Вы подсказать, нет ли возможности передавать класс activ именно первому элементу в списке ?

    Использую DLE, там есть несколько полей, в зависимости от того, заполнены они или нет, появляются табы, и допустим есть первый таю с классом activ не выведен, то остальные табы так же нельзя увидеть.

    Проще говоря, как передавать класс activ первому доступному табу ?

    1. 27 ноября 2016 г. в 19:47 / ответ на коммент Валентин

      После строк:

      (function($) {
      $(function() {
      

      добавьте:

      $('ul.tabs__caption li:nth-child(1), div.tabs__content:nth-child(2)').addClass('active');
      1. Валентин
        28 ноября 2016 г. в 09:48 / ответ на коммент Dimox

        Спасибо Вам большое! Как можно поддержать Ваш проект средствами ?

        1. 28 ноября 2016 г. в 11:41 / ответ на коммент Валентин

          Пожалуйста. Добавил в статью форму доната под блоком “Скачать”.

          1. Валентин
            28 ноября 2016 г. в 20:25 / ответ на коммент Dimox

            Отправил немного, спасибо еще раз за помощь!

            P.s – не подскажете в какую сторону копать, если нужно при переключении табов, вырубать встроенный iframe в таб, в том случа если это Media, Допустим Iframe с ютуба ?

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

            Понимаю что это уже не к Вам, но возможно с Вашим опытом можно что то подсказать.

            1. 28 ноября 2016 г. в 22:12 / ответ на коммент Валентин

              С подобным не сталкивался, к сожалению.

        2. Влад
          13 мая 2018 г. в 17:16 / ответ на коммент Валентин

          А за что спасибо, когда вкладку li не становится активной. И вообще этот копирайт зачем тут размещать да ещё и так дурно. Пишите свой.

  3. павел
    7 декабря 2016 г. в 11:41

    Уже писал спасибо автору скрипта, но мне не хватало анимированного перехода между табами, я немножко изменил скрипт вот что вышло. В код js добавлены fadeIn/fadeOut и delay(), для анимации табов, в css изменения минимальны, заменяем класс active на :first-of-type для того чтобы показывался первый таб по умолчанию.

    	$('ul.tabs__caption').on('click', 'li:not(.active)', function() {
    		$(this)
    			.addClass('active').siblings().removeClass('active')
    			.closest('div.tabs').find('div.tabs__content').fadeOut(1000).removeClass('active').eq($(this).index()).delay(1000).fadeIn(1000).addClass('active');
    	});
    
    .tabs__content{
        display: none;
    }
    .tabs__content:first-of-type{
        display: block;
    }
    

    Пример в действии можно посмотреть на jsfiddle

    1. Alex
      6 декабря 2017 г. в 16:51 / ответ на коммент павел

      СПАСИБО!

  4. Тимур
    22 декабря 2016 г. в 10:25

    Как мне кажется, если изобретать колесо, то колесо адаптивное.
    А то как неловко получается- табы не адаптивные, а весь сайт и в том числе табы “Похожие статьи” и “Рубрики” адаптивные. и если смотришь с телефона, то предлагаемое решение смотрится как костыль.

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

  5. Alex
    23 декабря 2016 г. в 23:10

    Отличный скрипт, спасибо! Дмитрий, подскажите, а как доработать первый вариант скрипта, чтобы продублировать вкладки (табы) сверху и снизу блока. Например, в мобильном блок очень длинный и чтобы не прокручивать наверх, хочу сделать дубликат вкладок.

  6. 14 апреля 2017 г. в 12:33

    огромное,- хотелось сказать денежное спасибо, но к сожелению на твоем ящике отсутствует реквизит “муравейника”, а по чужих ложить знаешь сам очень дорого;- просто огромейше спасибо за код, поставил все работает, а то если самому, да я учу джаваскрипт, то с моимы темпами, это бы произошло как ты и сам прекрасно понимаешь – “с тех пор прошло 2 года”, вот так!

  7. Дмитрий
    28 апреля 2017 г. в 12:59

    Вместо

    (function($) {
    $(function() {

    Можно написать
    jQuery(function($){

  8. Igor
    7 июня 2017 г. в 17:32

    Было бы здорово сделать адаптивность. Например на 480px превращать в аккордион.

  9. 6 июля 2017 г. в 12:09

    Супер! Спасибо вам огромное! Вкладки, создающиеся на лету по ссылкам + запоминание позиции – то, что я искал!

    Скажите, а можно добавить еще возможность закрывать после прочтения ненужные кладки?

    И еще, можно ли как-то прикрутить ко вкладкам какой-то параметр, чтобы на них можно было сослаться и отправить как ссылку ?

    1. 6 июля 2017 г. в 12:49 / ответ на коммент Mixa

      Скажите, а можно добавить еще возможность закрывать после прочтения ненужные кладки?

      Не понял, как это.

      И еще, можно ли как-то прикрутить ко вкладкам какой-то параметр, чтобы на них можно было сослаться и отправить как ссылку ?

      4-й пример.

  10. Alex
    6 декабря 2017 г. в 16:50

    Добрый день.

    Спасибо за код. Использую его постоянно.
    Подскажите, как сделать плавное появление табов при переключении?

    Спасибо!

    1. Alex
      6 декабря 2017 г. в 16:52 / ответ на коммент Alex

      Спасибо. Нашел нужный код чуть выше.

  11. Flector
    19 марта 2018 г. в 02:59

    использую код в админке wordpress (в интерфейсе плагина).
    сохраняю открытый таб в localStorage
    к сожалению – видно, что активная первая вкладка – и только потом скрипт переключает на сохраненную.

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

    1. 19 марта 2018 г. в 09:03 / ответ на коммент Flector

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

  12. Sabina
    30 мая 2018 г. в 15:15

    Здравствуйте! А можете подсказать, как сделать вкладки внутри каждой вкладки? Я вставляла предлагаемые Вами код в код каждой вкладки. По итогу отображается только первая активная вкладка, остальные не переключаются. Понимаю, что нужно что-то в коде поправить, но не могу догнать,что именно. Помогите, пожалуйста.
    http://dvernik.by/vhodnayadver-k69

    1. 30 мая 2018 г. в 18:28 / ответ на коммент Sabina

      Решение здесь.

      1. Sabina
        30 мая 2018 г. в 18:34 / ответ на коммент Dimox

        Спасибо огромное! Вы круты!

  13. Алексей
    30 сентября 2018 г. в 11:18

    Добрый день как отвязать якоря от tab(n), чтобы по ссылке #anchor-name переходило на нужную вкладку с якорем например по ID

  14. Татьяна
    8 ноября 2018 г. в 08:23

    Здравствуйте.
    Еще не пробовала ваш скрипт, но хочу сказать по поводу “изобретать колесо”: jquery-ui хорошая штука, но у него есть недостатки. Конкретно табы не имеют отличительного класса “активный-не активный”, только навигация. Из-за этого нельзя влиять на них с помощью CSS, а дизайнеры бывает такое нарисуют или заказчик придумает, что приходится “ломать” стандартную работу скрипта и класс тут очень будет кстати.

    Так что изобретайте и дальше, все пригодится )))

  15. Андрей
    19 февраля 2019 г. в 12:42

    Может быть уже писали не могу найти, как в этом примере вкладок сделать автоматическое переключение между вкладками?

  16. 9 марта 2019 г. в 13:52

    Адаптивные вкладки с трансформацией в аккордеон, кому интересно: https://github.com/WahaWaher/flextabs-js

  17. 20 июня 2019 г. в 19:26

    Спасибо! Очень круто работает. Переделал для трех вкладок, ничего лучше быть не может! Просто добавил поля в html. Прекрасно)

  18. Гость
    14 августа 2020 г. в 19:24

    на новой jquery стало ругаться на

    Uncaught Error: Syntax error, unrecognized expression: a[href*=#tab]

    это про 4-ый вариант скрипта

    1. 14 августа 2020 г. в 22:00 / ответ на коммент Гость

      Нужно заменить

      a[href*=#tab]

      на

      a[href*="#tab"]
      1. Гость
        14 августа 2020 г. в 22:01 / ответ на коммент Dimox

        Спасибо!

  19. Мария
    22 октября 2020 г. в 19:04

    Доброго времени суток! Почему ваш код не работает в IE11 :(
    Проверяла открыв ссылку первого примера в нем
    https://dimox.name/examples/universal-jquery-tabs-script/
    Не подскажите почему так? :(

    1. 22 октября 2020 г. в 20:18 / ответ на коммент Мария

      Исправил.

      1. Мария
        23 октября 2020 г. в 11:01 / ответ на коммент Dimox

        Спасибо ^_^
        А из-за чего этот глюк был?)

        1. 23 октября 2020 г. в 11:14 / ответ на коммент Мария

          Переносил сайт с http на https, но протокол был не везде изменен.

  20. Роман
    20 апреля 2023 г. в 16:25

    Огромная благодарность за скрипт!

Ваш комментарий

Жирный текст

Ссылка

Цитата

Внутристрочный код

CSS-код

HTML-код

JavaScript-код

PHP-код