移动端 触屏滑动条菜单(完善版)
1 | |
1 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 | <!doctype html> <html> <head> <meta charset= "utf-8" > <meta name= "viewport" content= "width=320,user-scalable=no" /> <title>菜单条</title> </head> <body> <style style= 'display:none' contentEditable> *{ margin:0; padding:0;} ul,li{ margin:0; padding:0; list-style:none;} #outer{ border:1px solid red; width:300px; height:46px; margin:20px auto; text-align:center; vertical-align:middle; line-height:46px; position:relative; overflow:hidden; background:#eee;} #outer:hover{ border-color:#333; cursor:pointer;} #inner{ position:absolute; left:0; top:1px; height:44px; line-height:44px; width:300px; background:#666; text-align:left; clear:both; overflow:hidden;} #inner li{ width:auto; height:44px; float:left; display:inline; padding:0 15px; text-align:center; } #inner li:hover{ background:#333;} #inner li a{font-size:14px; color:#fff; display:inline;width:auto; height:44px; line-height:44px; text-decoration:none;} .translateZ{ -webkit-transform:translateZ(0);transform:translateZ(0);-webkit-backface-visibility: hidden;backface-visibility: hidden;} .classtest{ background: #333;} </style> <div id= "outer" > <ul id= "inner" > <li><a href= "" >首页start</a></li> <li><a href= "" >美剧1</a></li> <li><a href= "" >电影1</a></li> <li><a href= "" >购物1</a></li> <li><a href= "" >时尚1</a></li> <li><a href= "" >新闻1</a></li> <li><a href= "" >其他1</a></li> <li><a href= "" >热点1</a></li> <li><a href= "" >电视1</a></li> <li><a href= "" >历史1</a></li> <li><a href= "" >首页2</a></li> <li><a href= "" >美剧2</a></li> <li><a href= "" >电影2</a></li> <li><a href= "" >购物2</a></li> <li><a href= "" >时尚2</a></li> <li><a href= "" >新闻2</a></li> <li><a href= "" >其他2</a></li> <li><a href= "" >热点2</a></li> <li><a href= "" >电视2</a></li> <li><a href= "" >结尾end</a></li> </ul> </div> touches:当前屏幕上所有手指的列表 targetTouches:当前dom元素上手指的列表,尽量使用这个代替touches changedTouches:涉及当前事件的手指的列表,尽量使用这个代替touches <script src= "../js/jquery-1.9.1.min.js" ></script> <script> window.onload= function (){ function getStyle(obj,attr){ return obj.currentStyle? obj.currentStyle[attr]:getComputedStyle(obj, false )[attr]; } var support = document.body.classList==undefined ? false : true ; var outer=document.getElementById( "outer" ); var inner=document.getElementById( "inner" ); var li=inner.getElementsByTagName( "li" ); var innerWd=0,i=0; for (;i<li.length;i++){ innerWd+=li[i].offsetWidth; } inner.style.width=innerWd+ 'px' ; var startX=0; var alls=0; var moveLeft=0; var iSpeedX = 0; var prevX = 0; var timer = null ; var resetStartX= true ; var maxDistance=parseInt(outer.offsetWidth-innerWd); //最大滑动距离 inner.addEventListener( "touchstart" ,start, false ); function start(e){ if (inner.offsetWidth<outer.offsetWidth) return ; //如果内部元素小于外框 不需要滑动 var e=e||window.event; e.preventDefault(); var touchs=e.touches[0], resetStartX= true ;; //startX=prevX=touchs.pageX; startX=touchs.pageX; prevX=touchs.pageX; alls= this .offsetLeft; inner.addEventListener( "touchmove" ,move, false ); inner.addEventListener( "touchend" ,end, false ); } function move(e){ var e=e||window.event; if (e.touches.length > 1 || e.scale && e.scale !== 1) return ; // 当屏幕有多个touch或者页面被缩放过,就不执行move操作 var touchs=e.changedTouches[0]; iSpeedX = touchs.pageX - prevX; //获取出手一瞬间的速度 prevX = touchs.pageX; //当前的始终覆盖上一个 moveLeft=touchs.pageX-startX; var that= this ; if (that.offsetLeft>=0){ if (resetStartX){ startX=touchs.pageX; resetStartX= false ; } that.style.left=moveLeft/3+alls+ 'px' ; } else if (that.offsetLeft<=maxDistance){ if (resetStartX){ startX=touchs.pageX; resetStartX= false ; } that.style.left=moveLeft/3+alls+ 'px' ; } else { that.style.left=moveLeft+alls+ 'px' ; } //this.style.webkitTransform='translateZ(0)'; //移动时候 缓存到GPU层 that.classList.add( 'translateZ' ); //classList 对已经增加的样式 不在判断是否添加 GPU缓存hack e.preventDefault(); } function end(){ var self= this ; clearInterval(timer); timer=setInterval( function (){ if (Math.abs(iSpeedX)<=1||self.offsetLeft>50||self.offsetLeft<maxDistance-50){ clearInterval(timer); //if(self.classList.contains('translateZ')){ //滚动停止 结束时候回收GPU 垃圾 // // self.classList.remove('translateZ'); //不知道怎么删除这样样式 // // self.setAttribute("class",''); // } if (self.offsetLeft>=0){ $(inner).animate({left:0},300, function (){ self.classList.remove( 'translateZ' ); //移除PGU hack }); } if (self.offsetLeft<maxDistance){ $(inner).animate({left:maxDistance+ 'px' },300, function (){ self.classList.remove( 'translateZ' ); //移除PGU hack }); } } else { iSpeedX *= 0.95; self.style.left = parseInt(self.offsetLeft + iSpeedX) + 'px' ; } },20); self.removeEventListener( "touchmove" ,move, false ); self.removeEventListener( "touchend" ,end, false ); //self.style.webkitTransform=''; } } </script> </body> </html> |
1 | |
优化滑动 setTimeout 相对减少时间计数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | function end(){ var self= this ; clearTimeout(timer); timer=setTimeout( function (){ if (Math.abs(iSpeedX)<=1||self.offsetLeft>50||self.offsetLeft<maxDistance-50){ clearTimeout(timer); //if(self.classList.contains('translateZ')){ //滚动停止 结束时候回收GPU 垃圾 // // self.classList.remove('translateZ'); //不知道怎么删除这样样式 // // self.setAttribute("class",''); // } if (self.offsetLeft>=0){ $(inner).animate({left:0},300, function (){ self.classList.remove( 'translateZ' ); //移除PGU hack }); } if (self.offsetLeft<maxDistance){ $(inner).animate({left:maxDistance+ 'px' },300, function (){ self.classList.remove( 'translateZ' ); //移除PGU hack }); } } else { iSpeedX *= 0.95; self.style.left = parseInt(self.offsetLeft + iSpeedX) + 'px' ; console.log( 'setTimeoutsss' ); setTimeout(arguments.callee,16) } },16); self.removeEventListener( "touchmove" ,move, false ); self.removeEventListener( "touchend" ,end, false ); //self.style.webkitTransform=''; } |
优化滑动 requestAnimationFrame 大幅减少时间计数
function end(){ var self=this, stopFlag=null; function sliderMove(){ if(Math.abs(iSpeedX)<=1||self.offsetLeft>50||self.offsetLeft=0){ $(inner).animate({left:0},300,function(){ self.classList.remove('translateZ'); //移除PGU hack }); } if(self.offsetLeft
requestAnimationFrame兼容处理:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | ;( function () { var lastTime = 0; var vendors = [ 'ms' , 'moz' , 'webkit' , 'o' ]; for ( var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame' ]; window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame' ] || window[vendors[x] + 'CancelRequestAnimationFrame' ]; } if (!window.requestAnimationFrame) window.requestAnimationFrame = function (callback, element) { var currTime = new Date().getTime(); var timeToCall = Math.max(0, 16 - (currTime - lastTime)); var id = window.setTimeout( function () { callback(currTime + timeToCall); }, timeToCall); lastTime = currTime + timeToCall; return id; }; if (!window.cancelAnimationFrame) window.cancelAnimationFrame = function (id) { clearTimeout(id); }; }()); // requestAnimationFrame polyfill by Erik Möller. // Fixes from Paul Irish, Tino Zijdel, Andrew Mao, Klemen Slavič, Darius Bacon // MIT license if (!Date.now) Date.now = function () { return new Date().getTime(); }; ( function () { 'use strict' ; var vendors = [ 'webkit' , 'moz' ]; for ( var i = 0; i < vendors.length && !window.requestAnimationFrame; ++i) { var vp = vendors[i]; window.requestAnimationFrame = window[vp+ 'RequestAnimationFrame' ]; window.cancelAnimationFrame = (window[vp+ 'CancelAnimationFrame' ] || window[vp+ 'CancelRequestAnimationFrame' ]); } if (/iP(ad|hone|od).*OS 6/.test(window.navigator.userAgent) // iOS6 is buggy || !window.requestAnimationFrame || !window.cancelAnimationFrame) { var lastTime = 0; window.requestAnimationFrame = function (callback) { var now = Date.now(); var nextTime = Math.max(lastTime + 16, now); return setTimeout( function () { callback(lastTime = nextTime); }, nextTime - now); }; window.cancelAnimationFrame = clearTimeout; } }()); |