Простой jQuery-скрипт для табов (вкладок)

13.07.2017

Самый простой пример реализации табов на сайте. Код максимально простой и легкий, не нужно никаких сторонних библиотек (кроме jquery) и никакого лишнего громоздкого кода. Весь HTML можно поменять под свою верстку, только не забудьте тогда поменять и код в скрипте, и в CSS.

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-->

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

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

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

Для красивого отображения на сайте нужно использовать свои стили.

Подключаем jQuery перед скриптом

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>

JS-скрипт для табов

Данный код вы помещаете в свой файл скриптов, если такого нету, то создаете его, например, scripts.js и подключаете после jquery таким образом:

<script src="js/scripts.js"></script>

Содержимое скрипта:

(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);

Пример табов, в котором запоминается активная вкладка после перезагрузки страницы (с помощью cookie)

Пример табов, в котором запоминается активная вкладка после перезагрузки страницы (с помощью cookie). HTML и CSS остается тот же, меняется только скрипт.

$(function() {

  function createCookie(name,value,days) {
    if (days) {
      var date = new Date();
      date.setTime(date.getTime()+(days*24*60*60*1000));
      var expires = "; expires="+date.toGMTString();
    }
    else var expires = "";
    document.cookie = name+"="+value+expires+"; path=/";
  }
  function readCookie(name) {
    var nameEQ = name + "=";
    var ca = document.cookie.split(';');
    for(var i=0;i < ca.length;i++) {
      var c = ca[i];
      while (c.charAt(0)==' ') c = c.substring(1,c.length);
      if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
    }
    return null;
  }
  function eraseCookie(name) {
    createCookie(name,"",-1);
  }

  $('ul.tabs__caption').each(function(i) {
    var cookie = readCookie('tabCookie' + i);
    if (cookie) {
      $(this).find('li').removeClass('active').eq(cookie).addClass('active')
      .closest('div.tabs').find('div.tabs__content').removeClass('active').eq(cookie).addClass('active');
    }
  });

  $('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');
    var ulIndex = $('ul.tabs__caption').index($(this).parents('ul.tabs__caption'));
    eraseCookie('tabCookie' + ulIndex);
    createCookie('tabCookie' + ulIndex, $(this).index(), 365);
  });

});
})(jQuery);

Пример табов, в котором запоминается активная вкладка после перезагрузки страницы (с помощью localStorage, меньше кода по сравнению с cookie)

Пример табов, в котором запоминается активная вкладка после перезагрузки страницы (с помощью localStorage, меньше кода по сравнению с cookie). HTML и CSS остается тот же, меняется только скрипт.

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

    $('ul.tabs__caption').each(function(i) {
      var storage = localStorage.getItem('tab' + i);
      if (storage) {
        $(this).find('li').removeClass('active').eq(storage).addClass('active')
        .closest('div.tabs').find('div.tabs__content').removeClass('active').eq(storage).addClass('active');
      }
    });

    $('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');
      var ulIndex = $('ul.tabs__caption').index($(this).parents('ul.tabs__caption'));
      localStorage.removeItem('tab' + ulIndex);
      localStorage.setItem('tab' + ulIndex, $(this).index());
    });

  });
})(jQuery);

Пример табов, в котором при переходе по ссылке с якорем, указывающим на номер таба, активируется соответствующий таб

Пример табов, в котором при переходе по ссылке с якорем, указывающим на номер таба, активируется соответствующий таб. HTML и CSS остается тот же, меняется только скрипт.

(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');
    });

    var tabIndex = window.location.hash.replace('#tab','')-1;
    if (tabIndex != -1) $('ul.tabs__caption li').eq(tabIndex).click();

    $('a[href*=#tab]').click(function() {
      var tabIndex = $(this).attr('href').replace(/(.*)#tab/, '')-1;
      $('ul.tabs__caption li').eq(tabIndex).click();
    });

  });
})(jQuery);

Полностью рабочий пример jquery-табов со своими стилями в вертикальном и горизонтальном виде:

See the Pen Jquery Tabs by Denis (@deniscreative) on CodePen.0

Сам скрипт целиком и полностью взят с сайта dimox.name

Рекомендую к прочтению:

Комментарии (23) к “Простой jQuery-скрипт для табов (вкладок)”

  • Evgeniya

    Спасибо!

    Ответить
  • Aleksander

    Спасибо большое)

    Ответить
  • Мари

    После перебирания мегатонн говнокода наконец то я нашла НОРМАЛЬНЫЙ легкий корректный код и видит Всевышний, я не люблю плагиат, но я только учусь, а сама так не написала бы. Надеюсь, вы не очень сердитесь. что я его позаимствовала и зверски расковыряла) Но даже это он пережил и позволил реализовать табы в табах. Большое человеческое спасибо.

    Ответить
    • Максим

      Для тех, кто учится, весь код – хороший. Нужно самому учиться писать не говнокод.

      Ответить
  • Alexander

    Огромное Вам спасибо! Вы мне сэкономили кучу времени!

    Ответить
  • Niko

    А как сделать так что бы вкладка после обновления страницы оставалась на том же?

    Ответить
    • Denis Creative

      Нужно использовать немного другой скрипт, с использованием localStorage:

      (function($) {
        $(function() {
      
          $('ul.tabs__caption').each(function(i) {
            var storage = localStorage.getItem('tab' + i);
            if (storage) {
              $(this).find('li').removeClass('active').eq(storage).addClass('active')
              .closest('div.tabs').find('div.tabs__content').removeClass('active').eq(storage).addClass('active');
            }
          });
      
          $('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');
            var ulIndex = $('ul.tabs__caption').index($(this).parents('ul.tabs__caption'));
            localStorage.removeItem('tab' + ulIndex);
            localStorage.setItem('tab' + ulIndex, $(this).index());
          });
      
        });
      })(jQuery);
      
      Ответить
  • Руслан

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

    Ответить
    • Denis Creative

      Попробуйте такой HTML:

      <ul class='tabs__caption'>
        <li class='active'><a href='#tab1'>1-я вкладка</a></li>
        <li><a href='#tab2'>2-я вкладка</a></li>
        <li><a href='#tab3'>3-я вкладка</a></li>
      </ul>
      

      и такой JS:

      (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');
          });
      
          var tabIndex = window.location.hash.replace('#tab','')-1;
          if (tabIndex != -1) $('ul.tabs__caption li').eq(tabIndex).click();
      
        });
      })(jQuery);
      

      Я проверил, вроде бы работает.

      Ответить
      • OF

        Здравствуйте.
        Спасибо за материал.
        Подскажите, пожалуйста, как дополнительно сделать, чтобы при переходе по ссылке несколько элементов с табами переключались?
        Чтобы понятнее было: у меня 5 блоков, в каждом по 3 вкладки. Над ними 3 кнопки. Необходимо, чтобы по нажатию кнопки 1-3, раскрывались табы 1-3.
        Вариант с якорем, к сожалению, раскрывает только 1ый элемент.

        Ответить
  • :))

    Почемуто Четвертая вкладка через букву р(Червертая ) :) самое смешное что по ссылке оригинала тоже самое:)

    Ответить
  • Георгий

    только я хотел позаимствовать ваш вариант табов, но… в мобильной версии, когда из-за маленькой ширины экрана закладки встают друг над другом, чтобы выбрать таб, надо нажимать на 50px ниже, чем его закладка находится :) садитесь, два =(

    Ответить
    • Denis Creative

      1. Скрипт рабочий.
      2. Стили для мобильного вы можете написать любые.
      3. В примере стили и скрипты упрощены до минимума, чтобы понять логику скрипта.

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

      Ответить
  • Степан

    Спасибо за самый рабочий и минималистичный пример!
    Но вот такой вопрос: А можно ли при 3-4 вкладках сделать некоторые из них неактивные?

    Ответить
  • Степан

    Прошу прощения за столь долгий ответ. Проблему я уже решил.
    Например, на сайте всегда присутствует несколько разделов (3-4), но на определенных страницах некоторые из разделов не имеют информации, и эти разделы необходимо скрыть, не скрывая кнопки. Решение простое – сделать неактивными сами кнопки (спокойно делается через CSS).
    Но вот другой вопрос: на странице есть заголовки, на которые можно перейти в меню разделов. За меню и заголовками закреплены определенные id.

    Заголовки:
    <h2><a id="A">A</a></h2>
    <h2><a id="B">B</a></h2>
    <h2><a id="C">C</a></h2>
    <h2><a id="D">D</a></h2>
    ...
    Меню:
    <a href="#A">A</a>
    <a href="#B">B</a>
    <a href="#C">C</a>
    <a href="#D">D</a>
    ...
    

    Также на этой странице присутствует несколько вкладок. Как сделать, чтобы меню тоже менялось при смене вкладок?
    Просто заметил особенность – скрипты и даже стандартные переходы по разделам не работают уже на 2 вкладке. На 1 все в порядке.

    Ответить
    • Denis Creative

      Добавьте пример на codepen.io – там будет понятнее, какие блоки существуют и как они выглядят, что должно происходить.

      Ответить
      • Степан

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

        Загвоздка в том, что в моем случае вкладки используются для, практически, одного и того же контента, за исключением некоторых блоков. В пример можно привести сайт с полезным советом для установки чего-либо. Один раздел отводится для Windows, другой для MacOS – чтобы пользователь знал, как действовать на любой из систем. Основные шаги одинаковые, но пути и некоторые действия различаются.

        И почему-то никакие скрипты, работающие на 1 вкладке, не хотят работать ни на 2, ни на любой другой вкладке. Поэтому я подумал про смену контента в меню разделов, чтобы заменить id (ведь, скорее всего, для продублированного контента невозможно применить один и тот же скрипт). К слову, в моем проекте контент находится в теге article, а меню разделов – в теге aside.
        Поэтому повторю вопрос: как сделать смену контента не только для основного блока, но и какого-нибудь другого на странице?

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

        Ответить
        • Denis Creative

          Интересно посмотреть на живой пример.

          Ответить
        • Denis Creative

          Получил пример на почту.

          1. На всей странице не должно быть одинаковых id – они уникальны и у каждого элемента должен быть свой id – это важно, из-за это и не работало меню.

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

          3. Более правильно будет вынести правое меню внутрь каждого таба со своими id и своими ссылками для этих id.

          4. Не совсем правильно, но чуть проще по верстке и чуть сложнее по скриптам я выслал код на почту. Там меню боковое остается одно, но при разных активных табах в этом меню подменяются ссылки для каждого активного Таба со своими уникальными ID.

          Ответить
  • Руслан

    Здравствуйте, спасибо большое за пример, сделал на его основе показ скриншотов, а думал городить какой-то скрипт слайдера. Не подскажите, можно как-то реализовать автоматическое переключение спустя какое-то время?
    Например, переключение вкладок через 1 секунду. Спасибо!

    Ответить
  • Верстальщик

    Здравствуйте! Подскажите, пожалуйста, можно ли сделать переключение вкладок через поле ?

    1-я вкладка
    2-я вкладка

    Ответить

Оставить комментарий