抽屉菜单在手机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 });