HTML5+CSS3实现抽屉菜单

标签: JavaScript HTML5 CSS3

抽屉菜单在手机native应用中很常见。比如下图酷狗手机版界面。左侧为操作菜单,默认不显示。需要时向右滑动界面,操作菜单将从左侧缓缓显示;不需要时向左滑动界面,操作菜单将隐藏在左侧边。操作菜单这种缓入缓出的用户体验非常不错。这里讲采用css3实现上述抽屉菜单效果。

抽屉菜单示例图

(以下实例请在基于webkit手机浏览器下访问)

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

源码下载

留言板
comments powered by Disqus