Macji Pro2010

记录一些应该记录的东东

Progressive Enhancement 的 Tab

November 3, 2008 - by Macji - HTML/CSS/JS/PHP - 渐进增强, tab, Progressive, Enhancement

大家一直在讲Progressive Enhancement,如果你不看英文,那么请看玉伯翻译的理解渐进增强(Progressive Enhancement)。也标题一下,做一个tab切换实例,来进一步说明Progressive Enhancement(渐进增强)。

需求:做一个tab,要求当用户禁止javascript后,tab还能照样使用。

貌似不能实现,可仔细想想是可以实现的,连这个都能实现,何况一个tab呢。。。

  1. 首先我们写html结构

    
    <div id="tab" class="mj">
    	<ul class="mj-nav">
    		<li class="first"><a href="#"><span>类目1</span></a></li>
    		<li><a href="#"><span>类目2</span></a></li>
    		<li><a href="#"><span>类目3</span></a></li>
    	</ul>
    	<div class="panel">
    		这是类目1
    	</div>
    	<div class="panel">
    		这是类目2
    	</div>
    	<div class="panel">
    		这是类目3
    	</div>
    </div>
    
    


    测试地址一
  2. 写上css

    
    .mj{
    	width:500px;
    	padding:10px 0;
    	border:solid 1px #bfbfbf;
    }
    .mj-nav, .mj-nav *{
    	background:url(cat_selector.png) no-repeat 100px 100px;
    }
    
    /* tab 导航条 */
    .mj .mj-nav{
    	height:25px;
    	padding:0 10px;
    	line-height:25px;
    	background-position:0 0;
    }
    .mj-nav li{
    	float:left;
    }
    .mj-nav a{
    	float:left;
    	padding-left:20px;
    }
    .mj-nav span{
    	display:block;
    	padding-right:20px;
    }
    .mj-nav a{
    	background-position:-500px 0;
    }
    .mj-nav .first a{
    	background-position:100px 100px;
    }
    .mj-nav .selected{
    	position:relative;
    	margin:0 -1px 0 0;
    }
    .mj-nav .selected a{
    	background-position:0 -25px;
    }
    .mj-nav .selected span{
    	background-position:100% -25px;
    }
    
    


    测试地址二
  3. 引入js,这里直接用Tbar,

    
    <script src="http://assets.taobaocdn.com/js/tbra/tbra-widgets.js?t=20081028.js" type="text/javascript"></script>
    <script type="text/javascript">
    TB.widget.SimpleTab.decorate('tab', {eventType:'click', currentClass:'selected'});
    </script>
    
    


    测试地址三
  4. ok,到这里我们的tab就算完成了。只要浏览器支持javascript,那么就可以使用我们的tab,但是,如果用户禁止了javascript,那后果该是怎样的呢?惨不忍睹。测试地址四
  5. 我们都知道锚点(url#xxx),定位到页面的位置。如果我们的锚点都在一个容器里面(div),并且这个容器只有100像素高(height:100px;overflow:hidden),然后我们锚点到它的字容器(字容器都是height:100px),那该是怎么样的呢?答案是可行的,可惜只有Opera不支持这种机制。
    
    //在原来的css基础上加上
    .panels{
    	height:50px;
    	overflow:hidden;
    }
    .panel{
    	height:50px;
    }
    
    <div id="tab" class="mj">
    	<ul class="mj-nav">	
    		<li class="first"><a href="#panel1"><span>类目1</span></a></li>
    		<li><a href="#panel2"><span>类目2</span></a></li>
    		<li><a href="#panel3"><span>类目3</span></a></li>
    	</ul>
    	<div class="panels">
    		<div id="panel1" class="panel">这是类目1</div>
    		<div id="panel2" class="panel">这是类目2</div>
    		<div id="panel3" class="panel">这是类目3</div>
    	</div>
    </div>
    
    
    


    我们只要再做一点点,就能让用户在没有javascript的情况下,也能使用tab,可乐而不为呢?测试地址五
  6. 但是,当页面很长时,点击切换后,我们tab导航看不到了,测试地址六
  7. 其实,我们只要在css上,调整一下就可以了。
    
    .mj{
    	position:relative;
    	width:500px;
    	padding:10px 0;
    	border:solid 1px #bfbfbf;
    }
    .mj-nav, .mj-nav *{
    	background:url(cat_selector.png) no-repeat 100px 100px;
    }
    /* tab 导航条 */
    .mj .mj-nav{
    	position:absolute;
    	left:0;
    	top:10px;
    	width:480px;
    	height:25px;
    	padding:0 10px;
    	line-height:25px;
    	background-position:0 0;
    }
    


    测试地址七
  8. 这时,javascript可以出场了。我们给其加上脚本。测试地址八
  9. 可恨的firefox 3,在有锚点,又有脚本,错位了。测试地址九
  10. 写上obj.scrollTop = 0;就可以了。

    
    var TabSelector = (function(){
    	var el = $D.get('tab');
    	if ( !el ) return false;
    	return {
    		init: function(){
    			$E.on(el.getElementsByTagName('ul')[0], 'click', function(){
    				$E.stopEvent(ev);
    			});
    			TB.widget.SimpleTab.decorate('tab', {
    				eventType:'click',
    				tabPanelClass:'panel',
    				currentClass:'selected'
    			});
    			$D.getLastChild(el).scrollTop = 0;
    		}
    	}
    })();
    $E.onDOMReady(TabSelector.init);
    
    


    比较完美的tab,测试地址十,如果再渐进增强,比如键盘事件,盲人触摸等,更极端的,当css失效时,但我没疯。

其实到第三步,一个tab就做好了,也不需要考虑这么多了,但考虑下去,不是很难,疯一次也是不错的。

7 条评论»