Вкладки и кнопка Back
Задача
Сделать так чтобы пользователь имел возможность открыть страницу сразу с открытой нужной вкладкой. Так же чтобы при навигации по вкладкам< работала кнопка «Back» в браузере.
Решение
В этом нам помогут Javascript событие hashchange и CSS3 псевдокласс :target (для красоты решения). Использование :target мы уже как-то рассматривали и в данном материале повторяться не будем.
Событие hashchange происходит при изменении URL, когда новый отличается от предыдущего только фрагментом идентификатора (часть URL, которая идет после знака # и называется хеш (hash)).
Как применять на практике продемонстрирует простой пример: сделаем блок, состоящий из трех вкладок:
<dl id="tabs"> <dt><a href="#menu">Меню</a></dt> <dd id="menu"><div>Содержимое вкладки меню</div></dd> <dt><a href="#info">Инфо</a></dt> <dd id="info"><div>Содержимое вкладки инфо</div></dd> <dt><a href="#photo">Фото</a></dt> <dd id="photo"><div>Содержимое вкладки фото</div></dd> </dl>
Замечу ,что <div> используется в декоративных целях.
В CSS тоже в целом ничего особенного и нового:
#tabs dt { float: left; line-height: 25px; margin: 0 2px 0 0; background: #ff8600; border: 1px solid #e47200; border-bottom: none; color: #f4ece1; -moz-border-radius: 8px 8px 0 0; -webkit-border-radius: 8px 8px 0 0; border-radius: 8px 8px 0 0; cursor: pointer; position: relative; } #tabs dt:first-child { margin-left: 10px; } #tabs dt a { display: block; height: 24px; color: #fff; text-decoration: none; padding: 0 22px; } #tabs dt.active { background: #77b001; border: 1px solid #679200; cursor: default; } #tabs dt a:hover { text-decoration: underline; } #tabs dt.active a { /* вид активной вкладки */ cursor: default; text-decoration: none !important; } #tabs dd { width: 100%; display: none; /* все вкладки по умолчанию не видимы */ float: right; margin: 0 0 0 -100%; padding-top: 25px; } #tabs dd.target, #tabs dd:target { display: block; /* вкладка получившая target становится видимой */ }
К этому добавляем небольшой JS:
jQuery(document).ready(function(){ var tabs = ["#menu", "#info", "#photo"], // создаем массив id вкладок для удобства проверок tabList = jQuery("#tabs"), ltie9 = jQuery.browser.msie && (jQuery.browser.version <= 9); /* ltie9 будет true если используется IE8 или ниже IE9 сюда попал из-за того что при нажатии на Back предыдущая вкладка не скрывалась */ // смена таба function changeTab(tabId){ if (!tabId) window.location.hash = tabs[0]; // если не указана вкладка показываем первую tabList.find(".active").removeClass("active"); jQuery(tabId).prev().addClass("active"); // активной вкладке добавляем класс чтобы придать нужный вид /* определив id вкладки можно выполнить какие-то дополнительные действия, например, выполнить ajax запрос */ switch (tabId) { case tabs[1]: jQuery("#info div").append("<p>динамически добавленный код</p>quot;); break; default: break; }; } // проверка хеша function checkHash(){ var tabId = window.location.hash, result = false; // для ИЕ6-8 эмуляция :target function setTarget(obj){ jQuery("#tabs dd").removeClass("target"); jQuery(tabId).addClass("target"); }; // при загрузке страницы проверяем какую вкладку следует открыть jQuery.each(tabs, function(){ if (tabId == this) { changeTab(tabId); result = true; ltie9 ? setTarget(tabId) : false; return false; }; }); if (result == false) changeTab(); }; // проверка хеша при загрузке checkHash(); // отслеживаем изменение хеша jQuery(window).bind("hashchange", function() { checkHash(); }); });
Демо пример. Проверено:
- IE 8-9
- Opera 11.11
- Firefox 8
- Safari 5
- Chrome
Следует отметить что событие hashchange многими браузерами поддерживается достаточно давно: IE8, FF 3.6, Opera 10.6 уже поддерживали данное событие. Если же требуется поддержка более старых браузеров, можно воспользоваться jQuery плагином от Ben Alman.
Материалы
- W3C :: 5.5.9 History traversal