http://www.cnblogs.com/dvbhack/archive/2009/04/17/portable-interchangeable-jquery-based-tabs.html
網頁上的空間是寸土寸金,雖然顯示器的分辨率越來越大,可是直到今天,網頁設計中仍然是以至少1024x768 像素的支持爲主,也就是說,每一屏頁面只有區區 955x600像素 的安全尺寸可以用而已。於是,爲了在有限的空間裏容納更多的內容,滑動門式的標籤切換(Tabs)方式越來越受歡迎。通過滑動門技術,可以在同一塊頁面區域內放置數倍的內容。根據用戶的選擇來決定顯示哪一部分。最近我在實際應用中,逐步完善出一種基於jQuery,但是比jQuery UI Tabs 插件更小巧也更通用的簡單 Tabs 實現。
最早的滑動門的技術,一般都是結合 onclick 或者 onmouseover 事件傳遞一個參數給 JS 函數,根據傳遞的參數來決定顯示哪一個標籤。比如:
function showTabs(n) {
var tabsNumber = 3;
for (i = 0; i < tabsNumber; i++) {
if (i == n) {
document.getElementById("tabPanel-" + i).style.display = "block";
} else {
document.getElementById("tabPanel-" + i).style.display = "none";
}
}
}
加入有這樣的一個函數,就可以在tab的標題按鈕中設置 onclick = “showTabs(1)”來設置第二塊內容顯示,而其它塊隱藏。
這種方式最大的缺點是:
- HTML代碼和JS代碼混合;
- 可擴展性差;
儘管可以通過window.onload綁定事件等方式來是實現JS代碼從HTML中分離,也可以把函數改得更復雜以實現通用性。但是總的來說,還是很難做到一處定義到處引用。
後來隨着各種JS類庫的出現,更強大的Tabs出現了,最出名的就是jQuery UI中的tabs插件。一旦加載了jQuery框架和jQuery UI插件,那麼要在頁面中實現Tabs,就變得簡單了許多。首先我們的頁面中的Tabs代碼這樣寫:
<div class="tabs">
<ul>
<li><a href="#panel-1">標籤一</a></li>
<li><a href="#panel-2">標籤二</a></li>
</ul>
<div id="panel-1">區域一</div>
<div id="panel-2">區域二</div>
</div>
注意:這裏的代碼非常乾淨,不含任何的JS代碼或者與文檔結構無關的定義。然後,在head區域,或者在頁面任何地方增加一段js代碼:
$(function() {
$(".tabs").tabs();
});
就實現了Tabs功能,這行JS代碼執行後,上面的HTML代碼就會變成:
<div class="tabs">
<ul class="ui-tabs-nav" jquery1239647486215="2">
<li class="ui-tabs-selected"><a href="#panel-1" jquery1239647486215="8">標籤一</a></li>
<li><a href="#panel-2" jquery1239647486215="9">標籤二</a></li>
></ul>
<div id="panel-1" class="ui-tabs-panel" jquery1239647486215="4">
區域一
</div>
<div id="panel-2" class="ui-tabs-panel ui-tabs-hide" jquery1239647486215="5">
區域二
</div>
</div>
結合我們自己編寫的css,或者jQuery UI 自帶的CSS,就可以實現滑動門效果。並且,由於jQuery的強大,我們可以在頁面中放置多組滑動門,然後一次性設定。
要說明的是,這個地方由於只啓用了jQuery UI 中的 Tabs 插件,因此生成的代碼還是比較乾淨的,只增加了 ui-tabs-xxxx 這幾個相關的css類。如果你同時包含了jQuery UI的其它插件,那麼即使不啓用,也會添加一堆的css定義。而且,jQuery UI Tabs 還提供了非常強大的控制功能,你可以動態地添加 tab,可以隨意更改激活事件,可以定義切換效果,還可以設置默認激活狀態和禁用等。
但是我在實際應用中遇到了一些問題,除了 jQuery UI 自帶的js腳本很大,css不符合實際應用需求外,還有一個最大的問題,你可能已經注意到了,在作爲導航的標籤定義中,每個標籤對應哪一個區域是用鏈接目標來定義的。比如 <a href="#panel-1">標籤一</a>和<div id="panel-1">區域一</div>對應,如果你的標籤和區域沒有對應起來,綁定tabs()就不起作用了。
而且,這種方式來帶來另一個麻煩,就是當我們需要給標籤加上鍊接的時候,沒辦法加。即使你將標籤的激活事件設置爲onmouseover而不是onclick,鏈接也不能實現,因爲鏈接用於指定目標了。這種需求在我們的實際應用中並不是不存在的。比如:
這兩個圖片中的tabs標籤,都要添加到對應的新聞類別或者論壇板塊的鏈接。這時候 jQuery UI的默認綁定就帶來了麻煩。
其實分析一下,我們在實現滑動門的時候,用以下HTML結構就可以滿足需要:
<div class="tabs">
<ul>
<li>標籤一</li>
<li>標籤二</li>
</ul>
<div>區域一</div>
<div>區域二</div>
</div>
藉助 jQuery 庫,我們可以通過 $(".tabs")找到要實現的標籤,然後 .find("li") 來找到要添加事件的元素,綁定事件的時候,我們可以通過該元素在$(".tabs li")集合中的索引值來明確是哪一個標籤被激活,然後對應索引值的panel顯示。代碼類似這樣:
<script type="text/javascript">
$(function() {
$(".tabs").find("li").onmouseover(function(e) {
if (e.target == this) {
var tabs = $(this).parent().children("li");
var panels = $(this).parent().parent().children("div");
var index = $.inArray(this, tabs);
if (panels.eq(index)[0]) {
tabs.removeClass("ui-tabs-selected")
.eq(index).addClass("ui-tabs-selected");
panels.addClass("ui-tabs-hide")
.eq(index).removeClass("ui-tabs-hide");
}
}
});
});
</script>
這段代碼只使用了兩個css類來處理,並且,自動判斷tabs和panels的對應狀態,假如你有4個tab,但是隻有前三個啓用了,那麼你只需要寫三個panel就可以,第四個panel不存在,則第四個tab自動不生效。
在實際使用中,會遇到一個問題,一般我們會給tab中的文字加鏈接,那麼當鼠標滑過這個tab的時候,如果指到了文字,那麼激發事件的對象有可能是a元素而不是li元素,則事件就不能正確激發。所以我們改進代碼如下:
<script type="text/javascript">
$(function() {
$(".ui-tabs-nav > li > a")onmouseover(function(e) {
if (e.target == this) {
var tabs = $(this).parent().parent().children("li");
var panels = $(this).parent().parent().parent().children(".ui-tabs-panel");
var index = $.inArray(this, tabs);
if (panels.eq(index)[0]) {
tabs.removeClass("ui-tabs-selected")
.eq(index).addClass("ui-tabs-selected");
panels.addClass("ui-tabs-hide")
.eq(index).removeClass("ui-tabs-hide");
}
}
});
});
</script>
與此對應的HTML結構是:
<div>
<ul class="ui-tabs-nav">
<li class="ui-tabs-selected"><a href="/bbs">論壇新帖</a></li>
<li><a href="/blog">最新博文</a></li>
</ul>
<div class="ui-tabs-panel">
<!--這裏調用最新論壇文章-->
</div>
<div class="ui-tabs-panel ui-tabs-hide">
<!--這裏調用最新博客文章-->
</div>
</div>
同時,我們有以下的css類定義:
.ui-tabs-nav
{
/*導航容器定義*/
}
.ui-tabs-nav li
{
/*默認標籤樣式*/
}
.ui-tabs-nav li.ui-tabs-selected
{
/*激活的標籤樣式*/
}
.ui-tabs-panel
{
/*默認的顯示區域樣式*/
}
.ui-tabs-hide
{
display: none;
}
這樣,就可以根據你的需要,結合自己的css,定製不同樣式的滑動門了。把相應的js代碼放到頁面中,那麼在頁面裏任何地方只要你按照HTML結構編寫了一段html,這段html就會自動變成滑動門。而不用在每個頁面裏單獨指定特定的selector來應用滑動門的tabs()方法。並且,根據需要給你的滑動門標籤添加需要的鏈接,或者不要鏈接(href="#" 或者 href="javascript:void(0)")。
這段滑動門代碼只要具有jQuery core 就可以正常運行,不需要加載jQuery UI。非常簡單,而且很通用,樣式上喜歡怎麼擴展都可以。
具體效果可以參見 http:/www.taihainet.com , 在 臺海網 首頁中,我一共應用了四個樣式共九組滑動門,代碼就只是上面給出的那一段。四個樣式列舉如下:
滑動門一:多個搜索表單,暫時只實現兩個,後面三個由於沒有對應的ui-tabs-panel,自動禁用,但是鏈接可以點擊。
滑動門二:多塊商務信息區域,其中第三個由於沒有對應的ui-tabs-panel,自動禁用。
滑動門三:新聞欄目切換,標籤中的文字鏈接到對應的新聞欄目。
滑動門四:論壇分板塊帖子調用。標籤中的文字鏈接到對應的論壇板塊。
本文首發自 刀刀博客