标准的、语义的、Unobtrusive的页签切换

标准

页签的流行
自从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 全部选择 提示:你可先修改部分代码,再按运行]

时间: 2025-01-30 08:49:51

标准的、语义的、Unobtrusive的页签切换的相关文章

标准的 语义的 非侵入的页签切换

标准 页签的流行 自从Yahoo!的首页引进页签(tab, 见下图)之后,这种可用性极佳的方式越来越受欢迎,用户也逐步习惯和喜欢上它,因为它可以在原有的空间上增加更多的可用信息,而且只需切换,不需刷新整个页面,浏览更舒畅.很多网站接受并使用,如新浪等. 页签的标记结构 那么,让我们来看看这些页签后的代码. 新浪完全不考虑什么标准,就是表格嵌套,我们略过不提.Yahoo!的XHTML形式是这样的: <div>  <ul>    <li>页签1</li>   

CSS:标准的 语义的 非侵入的页签切换

页签的流行 自从Yahoo!的首页引进页签(tab, 见下图)之后,这种可用性极佳的方式越来越受欢迎,用户也逐步习惯和喜欢上它,因为它可以在原有的空间上增加更多的可用信息,而且只需切换,不需刷新整个页面,浏览更舒畅.很多网站接受并使用,如新浪等. 页签的标记结构 那么,让我们来看看这些页签后的代码. 新浪完全不考虑什么标准,就是表格嵌套,我们略过不提.Yahoo!的XHTML形式是这样的: <div> <ul> <li>页签1</li> <li>

BootStrap中Tab页签切换实例代码_javascript技巧

关于$().tab()一般用来实现标签页和胶囊链接内容片段的切换,或是相关内容的页面导航: <ul class="nav nav-tabs" id="myTab"> <li class="active"><a href="#home">Home</a></li> <li><a href="#profile">Profile&

ligerui设置页签项标题setHeader方法的使用

在ligerui 官网看了下例子,发现setHeader方法不起作用,然后看了下该方法的代码,就自己写了替代方法. //设置页签项标题 setHeader: function(tabid,header) { $("li[tabid=" + tabid + "] a", this.tab.links.ul).text(header); }, 替代方法,其实差不多 <script type="text/javascript"> var n

交互设计:页签的操作方式

从日常理解页签:人们看书的时候,对于长篇的小说内容很难一目了然,不能直白的知道里面都包含哪些信息:也许对每个段落篇章进行分类,会更加形象:在读小学的时候,老师总让我们把那么长的一篇文章进行分段,然后起名,用一句话概括段落思想. 从互联网理解页签:这一类的内容太多了,页面总是不够承载:也许把相似的东西分成一类,用户可能更好理解.很多场景都是我们遇到过,想到过的.那么页签的运用也许可以解决此类问题. 思考页签的定义:可以把内容进行分类 给相似的东西起名 解决页面放不下的问题可以猜到包含的信息 可以作

Android中解决页签手指按下从左到右滑动的bug_Android

有一种方法可以阻止父层的View截获touch事件,就是调用 getParent().requestDisallowInterceptTouchEvent(true);方法. 一旦底层View收到touch的 action后调用这个方法那么父层View就不会再调用onInterceptTouchEvent了,也无法截获以后的action 在ViewPagerIndicator项目中找到TabPageIndicator该类,添加如下代码 @Override public boolean dispa

javascript-如何实现浏览器新建页签效果?

问题描述 如何实现浏览器新建页签效果? javascript效果 如何实现像浏览器一样新建页签效果,通过"+"添加新页签,默认选中当前新添加的页面.谢谢!

jquery tools之tabs 选项卡/页签_jquery

虽然方便好用,但是个人觉得其在UI方面的表现不是太出彩,今天无意中看到jquery tools--一种基于jquery的UI表现框架,其UI功能展示风格类似(或模仿)flex.该框架提供了tabs(选项卡/页签)overlay(覆盖层),tooltip(提示框),scrollable(滚动信息栏),expose(突出显示),flahembed(视频播放嵌入)六大类功能(其官方网站自称为六大工具),这六大类功能又是每个功能都有自己的独立支持包,不相互干扰,用户完全可以跟据自己需要下载,这样就减少了

jQuery Easyui Tabs扩展根据自定义属性打开页签_jquery

easyui是一个轻量级的后台管理系统框架,各种组件均有,使用简单方便,现在已经有免费版的License了. 1.增加扩展 <script type="text/javascript" > /** * @author {kexb} easyui-tab扩展根据id切换页面 */ $.extend($.fn.tabs.methods, { getTabById: function (jq, id) { var tabs = $.data(jq[0], 'tabs').tabs