標準的、語義的、Unobtrusive的頁簽切換

來源:互聯網
上載者:User
標準 頁簽的流行
自從Yahoo!的首頁引進頁簽(tab, 見下圖)之後,這種可用性極佳的方式越來越受歡迎,使用者也逐步習慣和喜歡上它,因為它可以在原有的空間上增加更多的可用資訊,而且只需切換,不需重新整理整個頁面,瀏覽更舒暢。很多網站接受並使用,如新浪等。


頁簽的標記結構
那麼,讓我們來看看這些頁簽後的代碼。

新浪完全不考慮什麼標準,就是表格嵌套,我們略過不提。Yahoo!的XHTML形式是這樣的:
<div>
<ul>
<li>頁簽1</li>
<li>頁簽2</li>
...
</ul>
</div>
<div>
<div>內容1</div><!--它們可能由Ajax載入-->
<div>內容1</div>
...
</div>

符合標準,但卻沒有語義。頁簽和相應內容沒有任何關聯。也就是說,在沒有CSS展現的情況下,使用者並不曉得頁簽究竟對應哪一塊內容。而且就JavaScript實現來說,必須對元素定義更多的id或者class作為調用鉤子(hook),容易造成代碼冗餘。有人對此作出改良,使用串連元素的hash(即#號後的欄位)跟內容進行關聯,即下面這種形式:
<div>
<ul>
<li><a href="#content1">頁簽1</a></li>
<li><a href="#content2">頁簽2</a></li>
...
</ul>
</div>
<div>
<div id="content1">內容1</div><!--它們可能由Ajax載入-->
<div id="content2">內容1</div>
...
</div>

這種方式對於機器來說,確實找到了關聯點,而且使用者點擊的時候,也能在hash的作用下(傳統說法中的“錨點”)調到相應的內容區塊。有進步,但還是不夠語義。

語義,語義,語義!
理想中標準的、語義的tab代碼應該是怎麼樣的呢?在我看來,應該是這樣:
<dl>
<dt>頁簽1</dt>
<dd>內容1</dd>
<dt>頁簽2</dd>
<dd>內容2</dd>
</dl>



當然,我認為並不是Yahoo!的設計師/開發人員並不瞭解語義,可能是由於某些特殊的需求在這種代碼下可能會實現不了,只好採取折衷方案。是的,在這種代碼形式下,語義雖能充分體現,但是要實現頁簽的表現形式,確實是一個難題。

解決之道
首先,請運行我們的示範,先自行分析一下。如果您使用Firefox,可以嘗試把CSS樣式禁用進行“欣賞”(如果您裝了Web developer toolbar,您可以CTRL + SHIFT + S)。繼續。

解決dt的橫排
dt與dd交錯,如何能夠使得dt排在一行上?well,理論不分析太多,要使它們在一起,我們假設dd不存在。這樣的話,使用float就能排在一起。既然dd不能不存在,ok,那麼讓它們脫離文檔流,如何做?position:absolute;就可以了。但是IE6有問題,wtf . 我的解決方案是,使用JavaScript把所有的dt湊一塊,這樣嚴重傷害了語義,但這隻是一個瀏覽器問題,而且是在有JavaScript的時候才產生語義問題,阿彌陀佛,辯證法認為事物都具兩面性。

解決dd的自適用高度
對於已經position:absolute;了的dd,無論是理論還是實踐,使用純CSS都沒有解決方案。同樣,我使用了JavaScript來動態計算它的每一次高度,然後賦予整個dl。

局限性與缺點
這樣做保證了標準、語義、Unobtrusive。但對於少部分擁有能解析CSS的先進瀏覽器但卻關閉了JavaScript的使用者來說,極有可能會被不能自適用高度的頁簽下的內容區塊擋住了跟隨在後的資訊。

s2uTab
很高興我能寫出一些實用的JavaScript,以上所提到的,我將之命名為s2uTab — 偏要解釋的話,它就是Standard, Semantic, Unobtrusive Tab的縮寫。首先,它很小,不依賴於任何庫,在IE6+, opera 9+, Firefox 2+均通過測試(若您有Safari,務必幫忙測試一下,謝謝)。其次,靈活,除了dl外無須任何鉤子,且頁簽數目靈活沒有限制。再次,您可以指定頁簽切換的事件形式,可以指定初始的頁簽是哪個。

用法
您可以為window.onload添加如下函數:
s2uTab(頁簽, 事件類型, 初始頁簽);

其中,頁簽指dl元素的引用,如果您傳入的是字串,則返回id是改字串的dl引用;事件類型是指,頁簽的啟用是點擊還是滑鼠移至上方,傳入click或者mouseover(注意:沒有”on”!)即可;初始頁簽是指您在初始化頁面時需要啟用的頁簽,注意,為符合編程習慣,請從0算起。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="zh" xml:lang="zh"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><meta name="developer" content="Realazy" /><title>標準的、語義的、Unobtrusive的頁簽切換</title><style type="text/css" media="screen">* {margin:0; padding:0;}body {width:42em; margin:3em auto; background:#ececec; color:#222; font: 1em/1.5 Arial,Helvetica,Sans-Serif;}h1 {margin-bottom:.2em; font-size:2em;}h2 {margin: .8em 0; font-family: Geogia,Times,Serif; font-size:1.4em;}pre {margin:1em 0; width:100%; overflow-x: auto; *padding-bottom:1em;}code {font-family:Monospace; font-size:.99em;}.copyleft {margin:1em 0;}/*tab樣式*/.tab {position:relative; width:20em;}.tab dt {position:relative; z-index:2; bottom:-1px; float:left; margin:0 4px; padding:0 12px; border:1px solid #ccc; background:#333; color:#fff; cursor:pointer;}.tab .current {border-bottom:1px solid #fff; font-weight:bold; background:#fff; color:#333;}.tab dd {position:absolute; z-index:1; top:1.6em; left:0; width:18em; padding:1em; border:1px solid #ccc; background:#fff;}</style><script type="text/javascript">var s2uTab = function(tabContainer, eventType, initial){if (typeof tabContainer == 'string') tabContainer = document.getElementById(tabContainer);eventType = 'on' + eventType;var dts = tabContainer.getElementsByTagName('dt');var dds = tabContainer.getElementsByTagName('dd');var pp = initial;addClass(dts[pp], 'current');var dth = dts[pp].clientHeight;var ddh = dds[pp].clientHeight;tabContainer.style.height = dth + ddh + 'px';for (var i = 0; i < dts.length; ++i){if (i != initial) dds[i].style.display = 'none';(function(){var p = i;dts[p][eventType] = function(){if (p != pp){addClass(dts[p], 'current');removeClass(dts[pp], 'current');dds[p].style.display = 'block';dds[pp].style.display = 'none';ddh = dds[p].clientHeight;tabContainer.style.height = dth + ddh + 'px';}pp = p;return false;}})();}if (ielt7){for (var i = 1; i < dts.length; ++i){tabContainer.insertBefore(dts[i], dds[0]) }if (dts[initial + 1]) dts[initial + 1][eventType]();else dts[initial - 1][eventType]();dts[initial][eventType]();}}var ielt7 = document.all && navigator.userAgent.indexOf('MSIE 7') < 0 && !window.opera;var hasClass = function(ele,cls) {return ele.className.match(new RegExp('(\\s|^)'+cls+'(\\s|$)'));}var addClass = function(ele,cls) {if (!this.hasClass(ele,cls)) ele.className += " "+cls;}var removeClass = function(ele,cls) {if (hasClass(ele,cls)) {var reg = new RegExp('(\\s|^)'+cls+'(\\s|$)');ele.className=ele.className.replace(reg,' ');}}</script><script type="text/javascript">// <![CDATA[window.onload = function(){s2uTab('tab', 'click', 2);s2uTab('tab2', 'mouseover', 0);}// ]]></script></head><body><h1>標準的、語義的、Unobtrusive的頁簽切換</h1><h2>例子1:點擊啟用</h2><pre><code>s2uTab('tab', 'click', 2);</code></pre><dl id="tab" class="tab"><dt>灞上秋居</dt><dd><p>灞原風雨定,</p><p>晚見雁行頻。</p><p>落葉他鄉樹,</p><p>寒燈獨夜人。</p><p>空園白露滴,</p><p>孤壁野僧鄰。</p><p>寄臥郊扉久,</p><p>何年致此身。</p></dd><dt>新嫁娘</dt><dd><p>三日入廚下,</p><p>洗手作羹湯。</p><p>未諳姑食性,</p><p>先遣小姑嘗。</p></dd><dt>塞下曲·其二</dt><dd><p>飲馬渡秋水,</p><p>水寒風似刀。</p><p>平沙日未沒,</p><p>黯黯見臨洮。</p><p>昔日長城戰,</p><p>鹹言意氣高。</p><p>黃塵足今古,</p><p>白骨亂蓬蒿。</p></dd></dl><h2>例子2:滑鼠移至上方啟用</h2><pre><code>s2uTab('tab', 'mouseover', 0);</code></pre><dl id="tab2" class="tab"><dt>灞上秋居</dt><dd><p>灞原風雨定,</p><p>晚見雁行頻。</p><p>落葉他鄉樹,</p><p>寒燈獨夜人。</p><p>空園白露滴,</p><p>孤壁野僧鄰。</p><p>寄臥郊扉久,</p><p>何年致此身。</p></dd><dt>新嫁娘</dt><dd><p>三日入廚下,</p><p>洗手作羹湯。</p><p>未諳姑食性,</p><p>先遣小姑嘗。</p></dd><dt>塞下曲·其二</dt><dd><p>飲馬渡秋水,</p><p>水寒風似刀。</p><p>平沙日未沒,</p><p>黯黯見臨洮。</p><p>昔日長城戰,</p><p>鹹言意氣高。</p><p>黃塵足今古,</p><p>白骨亂蓬蒿。</p></dd></dl><h2>CSS</h2><pre><code>.tab {position:relative; width:20em;}.tab dt {position:relative; z-index:2; bottom:-1px; float:left; margin:0 4px; padding:0 12px; border:1px solid #ccc; background:#333; color:#fff; cursor:pointer;}.tab .current {border-bottom:1px solid #fff; font-weight:bold; background:#fff; color:#333;}.tab dd {position:absolute; z-index:1; top:1.6em; left:0; width:18em; padding:1em; border:1px solid #ccc; background:#fff;}</code></pre></body></html>

    [Ctrl+A 全部選擇 提示:你可先修改部分代碼,再按運行]



相關關鍵詞:
相關文章

Cloud Intelligence Leading the Digital Future

Alibaba Cloud ACtivate Online Conference, Nov. 20th & 21st, 2019 (UTC+08)

Register Now >

Starter Package

SSD Cloud server and data transfer for only $2.50 a month

Get Started >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。