28
Меню “Вкладки”: переключение табов при помощи jQuery
24 коммент. » | Автор admin, рубрики JavaScript
В предыдущем посте Я рассказал о способе верстки вкладок(табов). Сейчас же Я хочу показать как реализовать переключение между вкладками при помощи jQuery, чтобы получилось вот так:
HTML: всё началось с разметки.
Поскольку процесс создания вкладок на HTML+CSS Я описал ранее, то покажу Вам мою адаптированную под этот пример HTML-разметку и перейду сразу к jQuery.
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 47 48 49 50 51 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>New Beautyfull Tabs from Belyash</title> <link rel="stylesheet" type="text/css" href="style.css" /> <meta http-equiv="Content-type" content="text/html;charset=UTF-8" /> <script type="text/javascript" src="jquery-1.4.2.min.js"></script> <script type="text/javascript"> /*тут будет наш код*/ </script> </head> <body> <div id="wrap"> <ul id="lineTabs"> <li><a href="#">Form</a></li> <li><a href="#">Text</a></li> <li><a href="#">Image</a></li> <li><a href="#" class="active">Image+Text</a></li> </ul> <div id="content"> <div id="tab1"> <h3>Напишите мне</h3> <form action="#"> <label for="name">Ваше имя</label><br /> <input name="name" type="text" /><br /> <label for="email">Ваш E-mail</label><br /> <input name="email" type="text" /><br /> <label for="comment"">Текст сообщения</label><br /> <textarea name="comment"></textarea> </form> </div> <div id="tab2"> <h3>Contrary to popular</h3> <p>Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old.</p> <h3>Richard McClintock</h3> <p>Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source.</p> <h3>Lorem Ipsum</h3> <p>Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of "de Finibus Bonorum et Malorum" (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, "Lorem ipsum dolor sit amet..", comes from a line in section 1.10.32.</p> </div> <div id="tab3"> <img src="images/giraf.jpg" /> </div> <div id="tab4" style="display:block;"> <img src="images/zayac.jpg" style="float: left; padding-right: 15px;" /> <p>Зайцы (лат. Leporidae) — семейство млекопитающих из отряда зайцеобразных, включающее в себя собственно зайцев (главным образом род Lepus, но также Pronolagus и Caprolagus) и кроликов (остальные роды). Зайцы распространены по всему миру, кроме Австралии и отдаленных островов, на многие из которых ввезены людьми. Отличаются от пищух развитыми задними конечностями, длинными ушами и наличием короткого хвоста.</p> </div> </div> </div> </body> </html> |
Для начала необходимо скачать файл библиотеки с официального сайта jQuery. После этого подключаем его в шапке нашей страницы:
1 | <script type="text/javascript" src="jquery-1.4.2.min.js"></script> |
jQuery: несколько строк.
Согласно официальной документации на сайте jQuery: метод .each() был создан для упрощения обхода в цикле элементов DOM-модели. Поэтому Я воспользовался именно этим методом. Собственно приведу сначала JS-код, а потом разберем.
1 2 3 4 5 6 7 8 9 10 11 12 | $(document).ready(function(){ $("#lineTabs li a").each(function (i) { $("#lineTabs li a:eq("+i+")").click(function(){ var tab_id=i+1; $("#lineTabs li a").removeClass("active"); $(this).addClass("active"); $("#content div").stop(false,false).hide(); $("#tab"+tab_id).stop(false,false).show(); return false; }) }) }) |
В первой строчке, мы проверяем загружена ли страница и только после этого приступаем к выполнению скрипта. Далее для набора ссылок-табов “#lineTabs li a” применяем метод .each() с параметром i.
1 2 | $(document).ready(function(){ $("#lineTabs li a").each(function (i) { |
Фильтр :eq(i) выбирает из текущего набора элемент с индексом i(порядковым номером, нумерация начинается с 0).
3 | $("#lineTabs li a:eq("+i+")").click(function(){ |
Вводим новую переменную tab_id для “ловли” блоков с id= “tab1″, “tab2″, “tab3″, “tab4″ (можно обойтись и без этой переменной, но тогда нужно начинать с id=”tab0″).
4 | var tab_id=i+1; |
Выбираем из DOM-модели все наши табы при помощи селектора “#lineTabs li a” и удаляем у них класс “active”.
5 | $("#lineTabs li a").removeClass("active"); |
Для текущего же таба(по которому кликнули в послежний раз) добавляем класс “active”.
6 | $(this).addClass("active"); |
На седьмой строке отбираем все блоки для наших вкладок и прячем их.
7 | $("#content div").stop(false,false).hide(); |
В восьмой строке: показываем див, который соответствует нашей вкладке. В конце обязательно возвращаем false, чтобы браузер не пытался выполнить переход по ссылке.
8 9 | $("#tab"+tab_id).stop(false,false).show(); return false; |
HTML, CSS, jQuery: собрали.
Ну вот вроде и всё. Таблицу стилей здесь приводить не буду, можете посмотреть её здесь или же скачав архив с примером.
Демо
Скачать архивом
UPDATE TO 24.02.2011
Пример, когда на странице необходимо более одного блока вкладок(табов):
Демо
Скачать архивом
Есть 24 коммент. к Меню “Вкладки”: переключение табов при помощи jQuery
Killalog | 9 Декабрь 2010 | 22:40
admin | 13 Декабрь 2010 | 23:54
Я использую плагин для WordPress WP-Syntax-. Удобный и поддерживает подсветку необходимых синтаксисов. Для подсветки нужного синтаксиса, достаточно прописать псевдоатрибут lang для тега pre, в который заключен код:
<pre lang=”LANGUAGE” line=”1″> … </pre> – line задает номер первой строки от которой пойдет отсчет. Значения LANGUAGE можно найти на сайте разработчика плагина.
intro | 22 Февраль 2011 | 9:32
То что надо.
Только как сделать, чтобы можно было на странице выводить две или три таких таблички. Попробовал – при нажатии, например, на любую вкладку второй таблички, закрываются все вкладки первой, а хотелось бы, чтобы последняя открытая оставалась.
И еще – таким же скриптом пользуется модуль gtranslate для перевода “на лету” и получается конфликт, переводчик не работает.
Подскажите, как реализовать задуманное. Спасибо.
admin | 24 Февраль 2011 | 1:00
intro, специально для Вас добавил апдейт к посту с примером(примерным) реализации нескольких блоков вкладок на странице. Скрипт функциональный и в нем нет необходимости делать правки при изменении количества блоков с вкладками.
intro | 28 Февраль 2011 | 18:04
Спасибо. Но вот вкладки не переключаются. А в javascript я ни бум-бум. Не могли бы исправить?
admin | 8 Март 2011 | 1:36
Конкретнее, пожалуйста: что именно у Вас не работает?
intro | 9 Март 2011 | 11:51
Со вкладками проблем нет, но вот переключаться не хотят, перебрасывает вверх страницы. Первоначальный вариант работает и из папки и при прописывании кода в шаблон (joomla), а вот вариант для независимых таблиц – нет. Насколько я понял, не работает js-код.
admin | 17 Апрель 2011 | 0:29
Перебрасывание вверх страницы происходит из-за того, что у Вас некорректно объявлено событие щелчка по табу. Посмотрите в примере http://web4develop.ru/wp-content/uploads/2010/08/tabs2.1/index.html
return | 7 Июль 2011 | 15:28
спасибо, замечательная статья, очень пригодилась! =)
Sergey | 7 Июль 2011 | 17:24
Добрый день,
вопрос от новичка, есть ли пример переключения между табами без использования jQuery. Здоровая сильно.Хотел на микроконтроллере попробовать.
Спасибо
Саня | 25 Июль 2011 | 19:38
автор нифига не че так и не объяснил, для новичков как я ни чо не понятно
admin | 25 Июль 2011 | 21:06
Саня, Вам бы для начала научится излагать свои мысли. Как говорится: “правильно составленный вопрос – это половина ответа”.
Chester | 16 Август 2011 | 7:05
Спасибо вам за классное меню. Реализовал на основе вашего примера меню навигации. Только вот небольшой недочет: когда переключаешься между табами и нажимаешь по ссылке к примеру из второго таба. После загрузки новой странички меню не запоминает, что мы находимся на 2-ом табе и загружается снова с первого. Это немного неудобно. Может быть у вас есть мысли, как сделать, чтобы менюшка стала более интеллектуальной и запоминала с какого таба был переход. Надеюсь выразился понятно ))
admin | 16 Август 2011 | 10:39
Chester. рад, что мой пост помог Вам. Насчет “недочета”: я бы не сказал, что это “недочет”, скорее Вам нужно доработать данный пример под свои конкретные цели. Так сходу могу предложить два варианта, для решения вашей задачи:
1) Используя Coockies, записывать в них последний активный таб, а при перезагрузке страницы JavaScript’ом выставлять необходимому табу class="active";
2) Возвращать от сервера HTML с уже проставленным class=”active” для конкретной вкладки.
Анатоль | 10 Октябрь 2011 | 10:52
Огромное спасибо за статью!
Менюшка работает отлично, но вот с моим мягко говоря “небольшим” опытом столкнулся с проблемой. Может поможете разрешить!?
Суть: Справа от меню еще один div с контентом. Суть проблемы выравнивание этих блоков.
С jQuery не очень дружу, по этому на чистом JavaScript (не без помощи Интернета) получилось так:
function eqHeight () { var a = document.getElementById("tabsContent"); var b = document.getElementById("rBar"); var aH = a.offsetHeight; var bH = b.offsetHeight; if (aH > bH) { a.style.height = (aH - 20) + 'px'; b.style.height = (aH - 20) + 'px'; } else if (aH < bH){ a.style.height = (bH - 20) + 'px'; b.style.height = (bH - 20) + 'px'; } }
Скрипт работает, вот только на событие onclick не вешается никак не пойму почему. Т.е. если переходишь на другую вкладку, с другой длиной правый div уже не подстраивается!
У Вас в меню клик по ссылке уже обрабатывается, может можно его как-то туда внедрить?
Анатоль | 10 Октябрь 2011 | 13:24
Пока вот что получается:
$("#tabs li a").each(function (i) { $("#tabs li a:eq("+i+")").click(function(){ var tab_id=i+1; var tallestcolumn = 0; currentHeight = $("#tab"+tab_id).height(); if(currentHeight > tallestcolumn) { tallestcolumn = currentHeight; } $("#rBar").height(tallestcolumn); }); });
У меня четыре вкладки в меню. В первых трех по одной строчке, в четвёртой строк десять (чисто для проверки). В правом сайдбаре (который ровняю) тоже одна строка и теже margin и padding что и в первых трех вкладках. Загружается с первой вкладкой, но при клике на первые три вкладке высота сайдбара резко уменьшается, так что аж контент выходит за бордюр. А вот при клике на четвертой вкладке (там где контента больше) все ровно!
Анатоль | 10 Октябрь 2011 | 13:28
Я извиняюсь, как уже говорил, сам не силен, поэтому переделываю чужое. Сразу не заметил много лишних переменных. Вот:
$("#tabs li a").each(function (i) { $("#tabs li a:eq("+i+")").click(function(){ var tab_id=i+1; var currentHeight = $("#tab"+tab_id).height(); $("#rBar").height(currentHeight); }); });
Вит | 15 Ноябрь 2011 | 11:13
После обновления страницы содержимое всех вкладок отображается вместе, после перехода по вкладкам они раскладываются по своим местам.
В чем причина?
admin | 15 Ноябрь 2011 | 11:20
Вит, скорее всего проблема в стилях. Необходим, чтобы первоначально вкладки были скрыты, для этого нужно прописать в стилях #content div { display:none; } . Посмотрите вот этот CSS из примера: http://web4develop.ru/wp-content/uploads/2010/08/tabs2/style.css
Вит | 15 Ноябрь 2011 | 12:35
Спасибо, помогло
Но появилась ещё одна проблемка.
Хочу в вкладки вставить комменты Фейсбук и Вконтакте. До Контакта ещё не дошёл, но с фесбуком уже проблема. Не хочет отображаться. Вне вкладки работает.
Может знаете с чем это связано? Если не по теме, то извиняюсь.
Вот код комментов Фейсбука:
(function(d, s, id) { var js, fjs = d.getElementsByTagName(s)[0]; if (d.getElementById(id)) {return;} js = d.createElement(s); js.id = id; js.src = "//connect.facebook.net/ru_RU/all.js#xfbml=1"; fjs.parentNode.insertBefore(js, fjs); }(document, 'script', 'facebook-jssdk'));
Вит | 15 Ноябрь 2011 | 13:49
Убрал CSS, все красота исчезла, но загрузились комменты, после перехода по вкладкам и обратно исчезли.
Чувствую придётся без вкладок поставить чьи-нить одни комменты.
admin | 15 Ноябрь 2011 | 14:00
Вит, всё дело в CSS, а именно в #content div { display:none; } — эта строчка назначает display:none; всем div’ам внутри #content. Задайте какой-нибудь класс для этих дивов-вкладок, например
div class="tab"
и измените свой CSS на #content div.tab { display:none; }.
Примеры из статьи — это всего лишь примеры, не стоит все классы один-в-один называть также.
Сергей | 14 Декабрь 2011 | 12:07
Спасибо за статью, если б не “любимый” IE в режиме совместимости…..
admin | 14 Декабрь 2011 | 12:16
Сергей, чтобы не включался режим совместимости в IE пропишите DOCTYPE на странице.
UPD: Только что проверил на кроссбраузерность примера в IE7, IE8, IE9 — всё норм. =)


Спасибо, отличная реализация
(скопировал к себе в блог, со ссылкой)
Ещё хочу спросить как Вы оформляете код с выводом по номерам?
Спасибо