html5+css3实现抽屉菜单

抽屉菜单在手机native应用中很常见。比如酷狗手机版的界面:

左侧为操作菜单,默认不显示。需要时向左滑动界面,操作菜单将从侧边缓缓展示出来,不需要时向右滑动界面,操作菜单又将隐藏在侧边而不会占位置,操作菜单这种缓入缓出用户体验非常不错。这里采用css3实现抽屉菜单效果。以下代码以及实例请在基于webkit手机浏览器下访问。

html代码如下:

1 <div id="container" class="container">
2     <div class="left"></div><!--左侧菜单-->
3     <div class="right"></div><!--右侧菜单-->
4 </div>     
View Code

样式代码如下:

 1 .container{
 2     position: relative;
 3     height: 300px;
 4     overflow-x: hidden;
 5 }
 6 .left, .right{
 7     top: 0;
 8     bottom: 0;
 9     position: absolute;
10 }
11 .left{
12     right: 0;
13     z-index: 1;
14     width: 150px;
15     background:black;
16 }
17 .right{
18     left: 0;
19     z-index: 2;
20     width: 100%;
21     background: red;
22 }
View Code

组件Drawer代码(依赖Zepto.js)如下:

  1 (function($, window, undefined){
  2     var hasOwnProperty = Object.prototype.hasOwnProperty;
  3 
  4     function Drawer(config){
  5         return this._init(config);
  6     }
  7 
  8     Drawer.prototype = {
  9         constructor: Drawer,
 10 
 11         _init: function(config){
 12             var me = this;
 13             me._config = $.extend({
 14                 //container
 15                 //nav
 16                 //main
 17                 dir: 'right',
 18                 transition: '-webkit-transform .4s ease-in-out'
 19             }, config);
 20             me._cacheParam()._bindEventListener();
 21             return me;
 22         },
 23         _cacheParam: function(){
 24             var me = this, config = me._config;
 25             for(var i in config){
 26                 if(hasOwnProperty.call(config, i)){
 27                     me['_' + i] = config[i];
 28                     config[i] = null;
 29                     delete config[i];
 30                 }
 31             }
 32             return me;
 33         },
 34         _bindEventListener: function(){
 35             var me = this,
 36                 $nav = me._nav,
 37                 $main = me._main,
 38                 $container = me._container,
 39                 direction = me._dir,
 40                 position = {x : 0, y : 0},
 41                 navWidth = $nav.width(),
 42                 transition = me._transition;
 43 
 44             $nav.attr('data-'+direction, '0');
 45             $container.on('touchstart', function(e){
 46                 var target = e.touches.item(0);
 47 
 48                 $main.css('-webkit-transition', 'none');
 49                 position.x = target.clientX;
 50                 position.y = target.clientY;
 51 
 52                 return false;                        
 53             }).on('touchmove', function(e){
 54                 var target = e.touches.item(0),
 55                     different = target.clientX - position.x,
 56                     distant = parseInt($main.attr('data-'+direction)||0, 10);
 57 
 58                 //滑动距离太短,则不处理
 59                 if(Math.abs(different) >= 5){
 60                     distant += different;
 61                     if(direction === 'left'){
 62                         //左侧菜单栏
 63                         if(distant <= 0){
 64                             distant = 0;
 65                         }
 66                         if(distant >= navWidth){
 67                             distant = navWidth; 
 68                         }                            
 69                     }else{
 70                         //右侧菜单栏
 71                         if(distant >= 0){
 72                             distant = 0;
 73                         }
 74                         if(distant <= -navWidth){
 75                             distant = -navWidth; 
 76                         }
 77                     }
 78                     $main
 79                       .attr('data-'+direction, distant)
 80                       .css('-webkit-transform', 'translate(' + distant + 'px,0)');
 81                 }                    
 82                 position.x = target.clientX;
 83                 position.y = target.clientY;                
 84                 return false;
 85             }).on('touchend', function(e){
 86                 var distant = parseInt($main.attr('data-'+direction), 10);
 87                 if(direction === 'left'){
 88                     distant = distant > navWidth/2 ? navWidth : 0;
 89                 }else{
 90                     distant = distant > -navWidth/2 ? 0 : -navWidth;
 91                 }
 92                 $main.css({
 93                     '-webkit-transform': 'translate(' + distant + 'px,0)',
 94                     '-webkit-transition': transition
 95                 }).attr('data-'+direction, distant);
 96                 return false;
 97             });
 98             return me;    
 99         }
100     };    
101     window.Drawer = Drawer;
102 })(Zepto, this);
View Code

初始化代码:

1 new Drawer({
2         dir: 'right',//菜单位于右边,默认值为左边,根据实际需要设置
3     container: $container,//总容器
4     nav: $container.children('.left'),//菜单栏
5     main: $container.children('.right')//主界面            
6 });
View Code

Demo附件

posted on 2014-04-03 00:18  shiny_bender  阅读(23210)  评论(0编辑  收藏  举报

导航