Очень хочется, чтобы при использовании закладок в дизайне, они имели специфический адрес URL. И при активировании закладки выводился URL, соответствующий текущему активному содержанию.
Если каждая закладка расположена по абсолютно разным адресам URL, то все просто. В коде HTML используется соответствующий класс для активной закладки, и выводится соответствующее содержание.
demosourse
Но если закладки являются "одной страницей", где разные панели выводятся и скрываются сразу или с помощью AJAX, задача становится сложнее. Обычный подход использовать персонифицированные ссылки, то есть:
http://example.com/#tab-three
С помощью псевдо-класса CSS3 :target можно реализовать функциональные закладки без использования JavaScript. Но на текущий момент закладки лучше создавать с помощью JavaScript.
Персонифицированные ссылки имеет несколько проблем:
При загрузке страницы по ссылке, браузер прокручивает содержание вниз так, чтобы элемент с ID, соответствующим ссылке, оказался в вверху страницы. Такое поведение не желательно. Проблему можно устранить с помощью preventDefault().
Изменение персонифицированной ссылки добавляет пункт в историю браузера. Поэтому при нажатии на кнопку "Назад" произойдет переключение на раздел с соответствующим идентификатором. При использовании ссылок такое поведение тоже не желательно.
Вот что мы будем делать:
Не будем использовать персонифицированные ссылки, а задействуем URL параметры (без прокручивания вниз).
Воспользуемся функцией history.replaceState(), так что изменение URL не будет действовать на кнопку "Назад".
Наш адрес URL будет выглядеть следующим образом:
http://example.com/?tab=tab-three
Код плагина выглядит следующим образом.
function($) {
// Определяем плагин
$.organicTabs = function(el, options) {
// Оригинальный вариант JavaScript
var base = this;
// Вариант jQuery
base.$el = $(el);
// Навигация для текущего селектора, переданная в плагин
base.$nav = base.$el.find(".nav");
// Выполняем один раз при вызове плагина
base.init = function() {
// Загружаем опции
base.options = $.extend({},$.organicTabs.defaultOptions, options);
// Скрываем то, что нужно скрыть
$(".hide").css({
"position": "relative",
"top": 0,
"left": 0,
"display": "none"
});
// При нажатии на закладку навигации...
base.$nav.delegate("a", "click", function(e) {
// Предотвращаем обработку по умолчанию
e.preventDefault();
// Вычисляем текущий список по классу CSS
var curList = base.$el.find("a.current").attr("href").substring(1),
// Список переместится в
$newList = $(this),
// Вычисляем ID нового списка
listID = $newList.attr("href").substring(1),
// Устанавливаем высоту внешнего контейнера для текущего внутреннего списка
$allListWrap = base.$el.find(".list-wrap"),
curListHeight = $allListWrap.height();
$allListWrap.height(curListHeight);
if ((listID != curList) && ( base.$el.find(":animated").length == 0)) {
// Гасим текущий список
base.$el.find("#"+curList).fadeOut(base.options.speed, function() {
// Выводим новый список в возвратной функции
base.$el.find("#"+listID).fadeIn(base.options.speed);
// выравниваем внешний контейнер так, чтобы он прижимался к новому списку
var newHeight = base.$el.find("#"+listID).height();
$allListWrap.animate({
height: newHeight
}, base.options.speed);
// Удаляем выделение - Добавляем закладку
base.$el.find(".nav li a").removeClass("current");
$newList.addClass("current");
// Изменяем адресную строку окна - добавляем параметр URL
if (window.history && history.pushState) {
// ПРИМЕЧАНИЕ: не берем в счет текущие параметры
history.replaceState("", "", "?" + base.options.param + "=" + listID);
}
});
}
// Не будет работать как обычная ссылка.
// Останавливаем дальнейшую обработку
return false;
});
};
base.init();
};
$.organicTabs.defaultOptions = {
"speed": 300,
"param": "tab"
};
$.fn.organicTabs = function(options) {
return this.each(function() {
(new $.organicTabs(this, options));
});
};
})(jQuery);
При вызове плагина можно использовать опции:
$.organicTabs.defaultOptions = {
"speed": 300, // Скорость смены закладки в миллисекундах
"param": "tab" //Добавляемая строка в адресе URL
};
Трюк заключается в том, что нам нужно вытянуть параметр URL, когда загружается страница, и передать его JavaScript для обработки. Придется использовать серверный язык (в примере использовался PHP):
// Обрабатываем активную закладку с помощью параметра URL
var tab = $("a[href='#<?php echo $_GET['tab']; ?>']");
if (tab.length) {
tab
.closest(".nav")
.find("a")
.removeClass("current")
.end()
.next(".list-wrap")
.find("ul")
.hide();
tab.addClass("current");
$("#<?php echo $_GET['tab']; ?>").show();
Данный код получает параметр URL, выделяет текущую закладку и выводит нужное содержание.