Wyszedłbym od implementacji no-js, bo napisanie takiej jest banalnie proste:
Kod
<!DOCTYPE html>
<html lang="pl" dir="ltr" class="no-js">
<head>
<meta charset="UTF-8">
<script>(function(H){H.className=H.className.replace(/\bno-js\b/,'js')})(document.documentElement)</script>
<title>Ehhhh</title>
<style>
.menu .tab
{
border: 1px #000 solid;
border-radius: 20px;
}
.menu .tab.active, .menu .tab:hover
{
background: #bbb;
}
.tabs .tab
{
display: none;
}
.tabs .tab:target, .js .tabs .tab.active
{
display: block;
}
</style>
</head>
<body>
<ul class="menu">
<li><a href="#tab1" class="tab active">tab1</a></li>
<li><a href="#tab2" class="tab">tab2</a></li>
</ul>
<div class="tabs">
<div id="tab1" class="tab">zawartość</div>
<div id="tab2" class="tab">zawartość drugiego taba</div>
</div>
</body>
</html>
Teraz zastanówmy się co dokładnie potrzebujemy od JS?
- Reagowania na zmianę w pasku adresu i zaznaczenia odpowiedniego linku w menu
- Jeśli nie ma nic w adresie, to zaznaczenie i wyświetlenie domyślnego tabu
Tyle - całą resztę robi za nas CSS.
Jak zatem będzie wyglądać tego typu funkcja w JS (jQuery)?
Kod
(function()
{
var changeTab = function(sel) //funkcja zmieniająca taba
{
var $menu = $('.menu') //bierzemy nawigację tabów
,$link = $menu.find('.tab[href=' + sel + ']') //pobieramy odpowiedni link
,$tabs = $('.tabs') //pobieramy kontener tabów
,$tab = $(sel); //pobieramy odpowiedni tab
$menu.find('a').removeClass('active'); //usuwamy klasę ze wszystkich elementów menu
$link.addClass('active'); //ustawiamy tę klasę odpowiedniemu linkowi
//powtarzamy to dla taba
$tabs.find('.tab').removeClass('active');
$tab.addClass('active');
}
,handleHash = function() //funkcja obsługująca hash
{
//operator trójkowy sprawdza czy coś mamy w adresie - jeśli tak, przekazuje to funkcji changeTab; jeśli nie - przekazuje [id] 1. tabu z # na początku
changeTab(location.hash ? location.hash : '#' + $('.tabs .tab').first().attr('id'));
};
//wywołujemy handleHash na starcie strony
handleHash();
//i przy zmianie hashu w adresie
$(window).on('hashchange', handleHash)
}());
Całość zatem wygląda następująco:
Kod
<!DOCTYPE html>
<html lang="pl" dir="ltr" class="no-js">
<head>
<meta charset="UTF-8">
<script>(function(H){H.className=H.className.replace(/\bno-js\b/,'js')})(document.documentElement)</script>
<title>Ehhhh</title>
<style>
.menu .tab
{
border: 1px #000 solid;
border-radius: 20px;
}
.menu .tab.active, .menu .tab:hover
{
background: #bbb;
}
.tabs .tab
{
display: none;
}
.no-js .tabs .tab:target, .js .tabs .tab.active
{
display: block;
}
</style>
</head>
<body>
<ul class="menu">
<li><a href="#tab1" class="tab">tab1</a></li>
<li><a href="#tab2" class="tab">tab2</a></li>
</ul>
<div class="tabs">
<div id="tab1" class="tab">zawartość</div>
<div id="tab2" class="tab">zawartość drugiego taba</div>
</div>
<script src="http://code.jquery.com/jquery.min.js"></script>
<script>(function()
{
var changeTab = function(sel) //funkcja zmieniająca taba
{
var $menu = $('.menu') //bierzemy nawigację tabów
,$link = $menu.find('.tab[href=' + sel + ']') //pobieramy odpowiedni link
,$tabs = $('.tabs') //pobieramy kontener tabów
,$tab = $(sel); //pobieramy odpowiedni tab
$menu.find('a').removeClass('active'); //usuwamy klasę ze wszystkich elementów menu
$link.addClass('active'); //ustawiamy tę klasę odpowiedniemu linkowi
//powtarzamy to dla taba
$tabs.find('.tab').removeClass('active');
$tab.addClass('active');
}
,handleHash = function() //funkcja obsługująca hash
{
//operator trójkowy sprawdza czy coś mamy w adresie - jeśli tak, przekazuje to funkcji changeTab; jeśli nie - przekazuje [id] 1. tabu z # na początku
changeTab(location.hash ? location.hash : '#' + $('.tabs .tab').first().attr('id'));
};
//wywołujemy handleHash na starcie strony
handleHash();
//i przy zmianie hashu w adresie
$(window).on('hashchange', handleHash)
}());
</script>
</body>
</html>
Voilla! Prosta implementacja tabów gotowa