tabs是現在網頁應用最廣的一種效果,jquery外掛程式和非jquery外掛程式也有不少,有一些朋友問我怎麼用jquery.ui.tabs的ajax怎麼只請求伺服器一次
原來我想其實很簡單,看看官方的API就瞭解,不過我在回複這些朋友之前,用firebug查看了官方的ui.tabs發現,聲明了ajax緩衝,每點一個tabs時,仍然會有伺服器請求
這應該是伺服器緩衝,而不是實際上我們要求的只ajax一次,不再請求伺服器了
接下來我找了一下其它的tabs外掛程式,基本上沒有符合要求的,不是太龐大就是太簡單,太過龐大的話不如用ui.tabs,文檔和代碼規範上都是可靠的
因此,自製一個簡潔的tabs外掛程式還是有必要的
在設計之前,先整理好思路,實現tabs,自動輪換,ajax等主要功能,然後是dom的排列形式,這裡採用傳統的
<div id="tabs">
<ul>
<li><a href="#tabs1">tabs1</a></li>
<li><a href="#tabs2" rel="ajax.htm">tabs2</a></li>
</ul>
<div id="tabs1">Hello World!</div>
<div id="tabs2"></div>
</div>
一個li對應一個div的方式,當ajax時,添加一個a的rel屬性,並將內容寫入對應的div中,再去掉rel屬性,這樣就只請求伺服器一次,接下來都是div已經寫入的內容了
我這裡沒有使用cookie,可以結合jquery.cookie外掛程式,這樣即使使用者關閉網頁下次再開啟,也不用請求伺服器了
一,首先寫個jquery外掛程式的閉包,園子裡這兩天有個朋友寫了javascript的閉包概念,挺好的,有興趣的朋友去看看
(function ($) {//code here})(jQuery);
二,外掛程式命名,這裡命名為aTabs,這樣綁定的時候可以用$(...).aTabs(),本人英文名Allen,所以用a字頭命名了~
$.fn.aTabs = function (options) {//api//main function}
三,把想好的功能寫成API,供外部修改
$.fn.aTabs.defaults = { firstOn: 0, className: 'selected', eventName: 'all', //click,mouserover,all loadName: '載入中...', //ajax等待字串 fadeIn: 'normal', autoFade: false, autoFadeTime: 3 };var opts = $.extend({}, $.fn.aTabs.defaults, options); //這裡可以將外部輸入的代替掉預設的值,$.extend作用詳見 http://api.jquery.com/jQuery.extend/,看不懂英文的直接看其中的例子就行
四,編寫主體功能,說明在代碼中看注釋
return this.each(function () { //這裡為每個綁定dom外掛程式 var target = $(this); var div = target.children().not("ul,span"); //所有的tabs顯示體div var tabs = target.find('ul:eq(0) li'); //所有的tabs頭部索引 function Tabs() { if ($(this).hasClass(opts.className)) { return false; } tabsShow(div, $(this)); return false; } function tabsShow(div, li, index) { div.stop(true, true).hide(); //自動輪換用 if (typeof (index) == "number") { if (li.find("a").attr("rel")) ajax(div, li); $(div[index]).stop(true,true).fadeIn(opts.fadeIn); tabs.stop(true, true).removeClass(opts.className); $(tabs[index]).stop(true, true).addClass(opts.className); } //非自動輪換 else { var tabBody = div.filter(li.find("a").attr("href")); if (li.find("a").attr("rel")) ajax(div, li); tabBody.stop(true,true).fadeIn(opts.fadeIn); tabs.stop(true, true).removeClass(opts.className); li.stop(true, true).addClass(opts.className); } } function ajax(div, li) { //這裡是關鍵ajax,通過操作rel的方式實現只請求伺服器一次 var href = li.find("a").attr("href"); var rel = li.find("a").attr("rel"); //ajax請求url var i = div.filter(href); //當前div if (rel) { //如果ajax請求url不為空白,只ajax一次 i.html(opts.loadName); $.ajax({ url: rel, cache: false, success: function (html) { i.html(html); }, error: function () { i.html('載入錯誤,請重試!'); } }); li.find("a").removeAttr("rel"); //只ajax一次 } } if (opts.autoFade) { var index = opts.firstOn + 1; setInterval(function () { if (index >= div.length) { index = 0; } tabsShow(div, $(this), index++); }, opts.autoFadeTime * 1000); } tabs.bind(opts.eventName == 'all' ? 'click mouseover' : opts.eventName, Tabs) //綁定事件 .filter(':first').trigger(opts.eventName == 'all' ? 'click' : opts.eventName); //自動觸發事件 });
最後,將以上整合,tabs外掛程式就誕生了,下面是全部源碼:
/** 作者:黑曜石*/(function ($) { $.fn.aTabs = function (options) { $.fn.aTabs.defaults = { firstOn: 0, className: 'selected', eventName: 'all', //click,mouserover,all loadName: '載入中...', //ajax等待字串 fadeIn: 'normal', autoFade: false, autoFadeTime: 3 }; var opts = $.extend({}, $.fn.aTabs.defaults, options); return this.each(function () { var target = $(this); var div = target.children().not("ul,span"); //所有的tabs顯示體div var tabs = target.find('ul:eq(0) li'); //所有的tabs頭部索引 function Tabs() { if ($(this).hasClass(opts.className)) { return false; } tabsShow(div, $(this)); return false; } function tabsShow(div, li, index) { div.stop(true, true).hide(); //自動輪換用 if (typeof (index) == "number") { if (li.find("a").attr("rel")) ajax(div, li); $(div[index]).stop(true,true).fadeIn(opts.fadeIn); tabs.stop(true, true).removeClass(opts.className); $(tabs[index]).stop(true, true).addClass(opts.className); } //非自動輪換 else { var tabBody = div.filter(li.find("a").attr("href")); if (li.find("a").attr("rel")) ajax(div, li); tabBody.stop(true,true).fadeIn(opts.fadeIn); tabs.stop(true, true).removeClass(opts.className); li.stop(true, true).addClass(opts.className); } } function ajax(div, li) { var href = li.find("a").attr("href"); var rel = li.find("a").attr("rel"); //ajax請求url var i = div.filter(href); //當前div if (rel) { //如果ajax請求url不為空白,只ajax一次 i.html(opts.loadName); $.ajax({ url: rel, cache: false, success: function (html) { i.html(html); }, error: function () { i.html('載入錯誤,請重試!'); } }); li.find("a").removeAttr("rel"); //只ajax一次 } } if (opts.autoFade) { var index = opts.firstOn + 1; setInterval(function () { if (index >= div.length) { index = 0; } tabsShow(div, $(this), index++); }, opts.autoFadeTime * 1000); } tabs.bind(opts.eventName == 'all' ? 'click mouseover' : opts.eventName, Tabs) //綁定事件 .filter(':first').trigger(opts.eventName == 'all' ? 'click' : opts.eventName); //自動觸發事件 }); };})(jQuery);