<!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>
優化滑動 setTimeout 相對減少時間計數
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<maxDistance-50){ 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 }); } window.cancelAnimationFrame(stopFlag);//可以取消該次動畫 stopFlag=null; sliderMove=null; //清空對象 console.log('requestAnimationFramessss'+sliderMove); }else{ iSpeedX *= 0.95; self.style.left = parseInt(self.offsetLeft + iSpeedX) + 'px'; console.log('滑動時候requestAnimationFrame次數'); stopFlag=requestAnimationFrame(arguments.callee); } } sliderMove(); self.removeEventListener("touchmove",move,false); self.removeEventListener("touchend",end,false); //self.style.webkitTransform=''; }
requestAnimationFrame兼容處理:
;(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; } }());
其他問題 用戶誤觸, css3持續時間 translate位移性能, touchmove 以及快速滑動 gpu的 合理調度
$(document).ready(function(e) { 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); //最大滑動距離 var stopFlag=null; 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.classList.add('translateZ'); //classList 對已經增加的樣式 不在判斷是否添加 GPU緩存hack inner.addEventListener("touchmove",move,false); inner.addEventListener("touchend",end,false); } function move(e){ var e=e||window.event; e.preventDefault(); 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; } var topNum=(touchs.pageX - startX)/3; that.style.left =topNum + 'px'; }else if(that.offsetLeft<=maxDistance){ if(resetStartX){ startX=touchs.pageX; resetStartX=false; } var midNum= (touchs.pageX - startX)/3 + (maxDistance); that.style.left = midNum+ 'px'; }else{ var botNum=touchs.pageX - startX + alls; that.style.left =botNum + 'px'; } //this.style.webkitTransform='translateZ(0)'; //移動時候 緩存到GPU層 } function end(e){ var e=e||window.event; e.preventDefault(); var self=this; var touchs=e.changedTouches[0]; var minDis= touchs.pageX-startX; function sliderMove(){ if(Math.abs(iSpeedX)<=1||self.offsetLeft>50||self.offsetLeft<maxDistance-50){ if(self.offsetLeft>=0){ console.log('llllllllllllllll'); $(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 }); } window.cancelAnimationFrame(stopFlag);//可以取消該次動畫 stopFlag=null; sliderMove=null; //清空對象 console.log('requestAnimationFramessss'+sliderMove); }else{ iSpeedX *= 0.95; self.style.left = parseInt(self.offsetLeft + iSpeedX) + 'px'; console.log('滑動時候requestAnimationFrame次數'); stopFlag=requestAnimationFrame(arguments.callee); } } if(Math.abs(minDis)>5) { //減少tap時候 bug 有時候輕輕一碰帶來的問題 用戶事項tap 時候 sliderMove(); } self.removeEventListener("touchmove",move,false); self.removeEventListener("touchend",end,false); //self.style.webkitTransform=''; } //} });
本文地址:http://www.cnblogs.com/surfaces/