抽屜菜單在手機native應用中很常見。比如酷狗手機版的界面:

左側為操作菜單,默認不顯示。需要時向左滑動界面,操作菜單將從側邊緩緩展示出來,不需要時向右滑動界面,操作菜單又將隱藏在側邊而不會占位置,操作菜單這種緩入緩出用戶體驗非常不錯。這里采用css3實現抽屜菜單效果。以下代碼以及實例請在基於webkit手機瀏覽器下訪問。
html代碼如下:
1 <div id="container" class="container"> 2 <div class="left"></div><!--左側菜單--> 3 <div class="right"></div><!--右側菜單--> 4 </div>
樣式代碼如下:
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 }
組件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);
初始化代碼:
1 new Drawer({ 2 dir: 'right',//菜單位於右邊,默認值為左邊,根據實際需要設置 3 container: $container,//總容器 4 nav: $container.children('.left'),//菜單欄 5 main: $container.children('.right')//主界面 6 });
