很久以前因為看別人的js選項卡代碼從而步入javascript的美麗大門,現在我也小小的寫一個小的教程,但愿能幫助道對js困惑的朋友。
一、結構
使用合理的HTML結構是javascript UI組件優雅的最重要條件之一,這里使用dl、dt、dd構建選項卡結構(js羅浮宮討論成果,見司徒正美:jquery tabs插件)
| 以下為引用的內容: <dl class="artTabs"> <dt id="tabs"><a href="#tabContent1" class="select">link1</a> <a href="#tabContent2">link2</a> <a href="#tabContent3">link3</a></dt> <dd id="tabContent1" style="display:block">tabContent1</dd> <dd id="tabContent2">tabContent2</dd> <dd id="tabContent3">tabContent3</dd> </dl> |
選項卡按鈕的錨點都指向內容,這樣在腳本與樣式失效的情況下仍然能夠進行基本的跳轉。
二、編寫核心javascript代碼
接下來就是js編寫。使用事件代理機制可以更加高效的處理業務,無需循環遍歷操作去給每個按鈕綁定事件,也能節省內存:
| 以下為引用的內容: var artTabs = function (bar, className, index) { var gid = function (id) {return document.getElementById(id)}, buttons = bar.getElementsByTagName('a'), selectButton = buttons[index], showContent = gid(selectButton.href.split('#')[1]); bar.onclick = function (event) { event = event || window.event; var target = event.target || event.srcElement; if (target.nodeName.toLowerCase() === 'a') { showContent.style.display = 'none'; showContent = gid(target.href.split('#')[1]); showContent.style.display = 'block'; selectButton.className = ''; selectButton = target; target.className = className; return false; }; }; }; |
是不是很小巧?以上代碼壓縮后貌似只有351字節:
| 以下為引用的內容: var artTabs=function(b,c,i,a){var g=function(x){return document.getElementById(x)},s=b.getElementsByTagName('a'),n=s[i],o=g(n.href.split('#')[1]);b.onclick=function(e){e=e||window.e;a=e.target||e.srcElement;if(a.nodeName.toLowerCase()==='a'){o.style.display='none';o=g(a.href.split('#')[1]);o.style.display='block';n.className='';n=a;a.className=c;return false}}} |
調用范例:artTabs(document.getElementById(‘tabs’), ‘select’, 0);
查看演示:artTabs1.html
三、優化接口
是否發現這個剛出爐的選項卡參數有點麻煩?如果要支持鼠標靠近觸發怎么辦?或者點擊選項卡的時候要采用ajax加載填充內容要如何處理回調函數?
顯然我們前面的API設計并不能優雅的處理這些需求,我們改用字面量的方式傳入參數,增加一些新接口,如:
| 以下為引用的內容: var artTabs = function (bar, config) { var gid = function (id) {return document.getElementById(id)}; config = config || {}; var bar = typeof bar === 'string' ? gid(bar) : bar, className = config.className || 'select', callback = config.callback || function () {}, isMouseover = config.isMouseover, buttons = bar.getElementsByTagName('a'), selectButton = buttons[ config.index || function () { var ret = 0; for (i = 0; i < buttons.length; i++) { if (buttons[i].className === className) ret = i; }; return ret; }() ], showContent = gid(selectButton.href.split('#')[1]), fn = function (event) { event = event || window.event; var target = event.target || event.srcElement; if (target.nodeName.toLowerCase() === 'a') { showContent.style.display = 'none'; showContent = gid(target.href.split('#')[1]); showContent.style.display = 'block'; selectButton.className = ''; selectButton = target; target.className = className; target.focus(); callback(selectButton, showContent); return false; }; }; if (isMouseover) bar.onmouseover = fn; bar.onclick = fn; }; |
調用范例:artTabs(‘tabs’);
查看演示:artTabs2.html
四、擴展
原生代碼執行效率往往會比框架高,當然我們還是可以很簡單寫幾行代碼為jQuery獻身,成為其插件:
| 以下為引用的內容: jQuery.fn.artTabs = function (config) { return this.each(function () { artTabs(this, config); }); }; |
調用范例:jQuery(‘.artTabs > dt’).artTabs();
查看演示:artTabs3.html
以上實現了選項卡最基本的功能,如果需要可以連選項卡HTML結構都封裝進去、歷史記錄支持、URL記憶支持、Ajax數據加載支持等……
planeArt原創文章,原文地址:http://www.planeart.cn/?p=987