直接上圖,左右拖拽輪播圖時候 上下事件會存在衝突;翻看了 swipe.js源碼,找到了解決辦法;css
isScrolling = !!( isScrolling || Math.abs(movPos.x-startPos.x) < Math.abs(movPos.y-startPos.y) );
源碼附錄:html
<!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta name="viewport" content="initial-scale=1.0,user-scalable=no,maximum-scale=1,width=device-width" /> <title>ios 輪播圖簡版</title> <style> *{ margin:0; padding:0;} html{-webkit-box-sizing:border-box;margin:0 auto;height:100%; font-size:16px;-webkit-touch-callout:none;-webkit-user-select:none;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent; max-width:640px;} body,html{overflow-x:hidden;width:100%;min-width:320px; margin:0 auto;background:#fff;} ul,li{margin:0; padding:0;list-style:none;} #refreshTxt{ width:100%; text-align:center; height:35px; font-size:13px; line-height:35px; color:#888;position:absolute; left:0; top:0; z-index:1; overflow:hidden; display:block;} .flexbox{display: -webkit-box; display: -moz-box;display:box; display: -webkit-flex; display: -ms-flexbox; display: flex; display: table\9; } .flexbox .flex1{-webkit-box-flex: 1; -moz-box-flex: 1; -webkit-flex: 1; -ms-flex: 1; flex: 1; display: table-cell\9;} .disbox{ display:-webkit-box;display:-moz-box; display:-o-box; display:box;} .translateZ{ -webkit-transform:translateZ(0);transform:translateZ(0);-webkit-backface-visibility: hidden;backface-visibility: hidden;} #wraps{ max-width:640px; margin:0 auto; border:2px solid red; box-sizing:border-box; background:#333; color:#fff; position:relative; z-index:99;} #outer{ display:block; min-height:100px; height:260px; margin:10px auto 0; position:relative; overflow:hidden; box-sizing:border-box; background:#999;-webkit-transform-style:preserve-3d; } #inner{ min-height:100px; -webkit-backface-visibility:hidden;display:block;box-sizing:border-box;display:-webkit-box;display:-moz-box; display:-o-box; display:box;} #inner .memeber_content_one{ min-height:100px; border: 3px solid #fff; height:auto; overflow:hidden; display:block; width:100%; box-sizing:border-box; text-align: center; } #inner .memeber_content_one a{ display: block} #inner .memeber_content_one img{ width:100%; } #selects{ position:absolute; bottom:20px; right:50px; z-index:666;} #selects span{ float:left; padding:5px; background:#fff; margin-right:5px; border-radius:50%;} #selects .on{background:red;} </style> </head> <body> <P style="padding:10px 0; background:#eee; text-align:center ">導航欄</P> <p id="refreshTxt" style='top:40px'>下拉刷新</p> <div id="wraps"> <P style="padding:30px 0">http://www.cnblogs.com/surfaces</P> <div id="outer" > <div id="inner" > <div class="memeber_content_one "><a href="https://www.qq.com" target="_blank"> <img src="../loveImg/QioA-fxehfqi8208393.jpg"></a></div> <div class="memeber_content_one "><a href="https://www.baidu.com" target="_blank"><img src="../loveImg/13443924,1920,1080.jpg"></a></div> <div class="memeber_content_one "><img src="../loveImg/1459302987961.jpg"></div> </div> <div id="selects"><span class="on"></span><span></span><span></span></div> </div> <!--<script src="mov3.js"></script>--> <P style="padding:30px 0"><input type="text" ></P></P> <P style="padding:30px 0">http://www.cnblogs.com/surfaces</P> <P style="padding:30px 0">http://www.cnblogs.com/surfaces</P> <P style="padding:30px 0">http://www.cnblogs.com/surfaces</P> <P style="padding:30px 0">http://www.cnblogs.com/surfaces</P> <P style="padding:30px 0"><input type="text" ></P></P> <P style="padding:30px 0">http://www.cnblogs.com/surfaces</P> <P style="padding:30px 0">http://www.cnblogs.com/surfaces</P> <P style="padding:30px 0">http://www.cnblogs.com/surfaces</P> <P style="padding:30px 0">http://www.cnblogs.com/surfaces</P> </div> <script> /*transfrom.js*/ ;(function(window,document,undefined){var prefix=function(){var div=document.createElement("div");var cssText="-webkit-transition:all .1s;-moz-transition:all .1s; -Khtml-transition:all .1s; -o-transition:all .1s; -ms-transition:all .1s; transition:all .1s;";div.style.cssText=cssText;var style=div.style;var dom="";if(style.webkitTransition){dom="webkit"}if(style.MozTransition){dom="moz"}if(style.khtmlTransition){dom="Khtml"}if(style.oTransition){dom="o"}if(style.msTransition){dom="ms"}div=null;if(dom){return{dom:dom,lowercase:dom,css:"-"+dom+"-",js:dom[0].toUpperCase()+dom.substr(1)}}else{return false}}();var transitionEnd=function(){var el=document.createElement("div");var transEndEventNames={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd",msTransition:"MSTransitionEnd",transition:"transitionend"};for(var name in transEndEventNames){if(el.style[name]!==undefined){return transEndEventNames[name]}}el=null;return false}();var supportedTransforms=/^((translate|rotate|scale)(X|Y|Z|3d)?|matrix(3d)?|perspective|skew(X|Y)?)$/i;var dasherize=function(str){return str.replace(/::/g,"/").replace(/([A-Z]+)([A-Z][a-z])/g,"$1_$2").replace(/([a-z\d])([A-Z])/g,"$1_$2").replace(/_/g,"-").toLowerCase()};var transform=function(obj,properties,duration,ease,callback,delay){if(!obj){return}if(typeof duration=="function"){callback=duration,ease=undefined,duration=400,delay=delay}if(typeof ease=="function"){callback=ease,ease=undefined,delay=delay}if(duration){duration=typeof duration=="number"?duration:400};if(typeof callback == 'number') delay=callback,callback=undefined;delay=(typeof delay=="number")?delay:0;var nowTransition=prefix.js+"Transition";var nowTransform=prefix.js+"Transform";var prefixcss=prefix.css;if(!prefix.js){nowTransition="transition";nowTransform="transform";prefixcss=""}var transitionProperty,transitionDuration,transitionTiming,transitionDelay;var key,cssValues={},cssProperties,transforms="";var transform;var cssReset={};var css="";var cssProperties=[];transform=prefixcss+"transform";cssReset[transitionProperty=prefixcss+"transition-property"]=cssReset[transitionDuration=prefixcss+"transition-duration"]=cssReset[transitionDelay=prefixcss+"transition-delay"]=cssReset[transitionTiming=prefixcss+"transition-timing-function"]="";for(key in properties){if(supportedTransforms.test(key)){transforms+=key+"("+properties[key]+") "}else{cssValues[key]=properties[key],cssProperties.push(dasherize(key))}}if(transforms){cssValues[transform]=transforms,cssProperties.push(transform)}if(duration>0&&typeof properties==="object"){cssValues[transitionProperty]=cssProperties.join(", ");cssValues[transitionDuration]=duration+"ms";cssValues[transitionTiming]=(ease||"linear");cssValues[transitionDelay]=delay+"ms"}for(var attr in cssValues){css+=dasherize(attr)+":"+cssValues[attr]+";"}obj.style.cssText=obj.style.cssText+css;if(!callback){return}var fired=false;var handler=function(){callback&&callback.apply(obj,arguments);fired=true;if(obj.removeEventListener){obj.removeEventListener(transitionEnd,arguments.callee,false)}};if(obj.addEventListener){obj.addEventListener(transitionEnd,handler,false)}if(!transitionEnd||duration<=0){setTimeout(function(){handler()});return}setTimeout(function(){if(fired){return}handler()},(duration+delay)+25)};window.transform=transform})(window,document); </script> <script> var prefix = function() { //獲取前綴 var div = document.createElement('div');//創建臨時DIV容器 var cssText = '-webkit-transition:all .1s;-moz-transition:all .1s; -Khtml-transition:all .1s; -o-transition:all .1s; -ms-transition:all .1s; transition:all .1s;'; div.style.cssText = cssText; var style = div.style; var dom=''; if (style.webkitTransition) { dom ='webkit'; }else if (style.MozTransition) { dom='moz'; }else if (style.khtmlTransition) { dom='Khtml'; }else if (style.oTransition) { dom='o'; }else if (style.msTransition) { dom='ms'; } if(dom){////style.transition 狀況 return dom; } div=null; ////去掉沒必要要的數據存儲,便於垃圾回收 }(); function getTransform(el) { //獲取translate var pre='-'+prefix+'-transform'; var transform = window.getComputedStyle(el, null)[pre]|| window.getComputedStyle(el, null).getPropertyValue('transform'); var results = transform.match(/matrix(?:(3d)\(-{0,1}\d+(?:, -{0,1}\d+)*(?:, (-{0,1}\d+))(?:, (-{0,1}\d+))(?:, (-{0,1}\d+)), -{0,1}\d+\)|\(-{0,1}\d+(?:, -{0,1}\d+)*(?:, (-{0,1}\d+))(?:, (-{0,1}\d+))\))/); if(!results) return [0, 0, 0]; if(results[1] == '3d') return results.slice(2,5); results.push(0); return results.slice(5, 8); // returns the [X,Y,Z,1] values } var userAgent=window.navigator.userAgent.toLowerCase(), isWebkit = userAgent.indexOf('webkit') !== -1, isiOS = userAgent.indexOf('iphone') !== -1 ; //iphone終端 //var isTouch=!! ("ontouchstart" in window )|| (window.DocumentTouch && document instanceof DocumentTouch); var isTouch=!! ("ontouchstart" in window ); if(isTouch){ var touchEvent ={ touchstart:"touchstart", touchmove:"touchmove", touchend:"touchend" } var outer = document.getElementById('outer'); var inner = document.getElementById('inner'); var aLi = inner.getElementsByClassName("memeber_content_one"); var w = parseInt(aLi[0].offsetWidth); //var innerWid=inner.style.width = aLi.length * w + 'px'; //直接經過 display:-webkit-box; 設置外圍寬度 再也不須要計算 var innerWid= aLi.length * w + 'px'; var iNow=0; var downLeft = 0; var maxDiatance=parseInt(w)-parseInt(innerWid); var startPos={}; var isScrolling; inner.addEventListener(touchEvent.touchstart,function(e){ var self=this; var e=e||window.event; var touchs = e.changedTouches[0]; //手指頭的一個 startPos={ x : touchs.pageX||touchs.clientX, y : touchs.pageY||touchs.clientY, startTime:+new Date } downLeft= parseInt(getTransform(inner)[0]); var isMoveScale=true; isScrolling = undefined; //這個參數判斷是垂直滾動仍是水平滾動 默認0水平 inner.style.webkitTransition=inner.style.transition =" 0s "; inner.addEventListener(touchEvent.touchmove,move,false); inner.addEventListener(touchEvent.touchend,end,false); function move(){ var e=e||window.event; if (e.touches.length > 1 || e.scale && e.scale !== 1) return;// // 當屏幕有多個touch或者頁面被縮放過,就不執行move操做 var touchs = e.changedTouches[0], self=this; var movPos={ x : touchs.pageX||touchs.clientX, y : touchs.pageY||touchs.clientY } if ( typeof isScrolling == 'undefined') { isScrolling = !!( isScrolling || Math.abs(movPos.x-startPos.x) < Math.abs(movPos.y-startPos.y) ); } //console.log('222isScrolling'+isScrolling); if (!isScrolling) { e.preventDefault(); var translateX=getTransform(self)[0]; if(translateX>=0){//若是從左側向右到盡頭 if(isMoveScale){ startPos.x = touchs.pageX||touchs.clientX; isMoveScale=false; } var one=parseInt((touchs.pageX-startPos.x)*0.4); inner.style.webkitTransform=inner.style.transform="translate3d("+one+"px,0,0)"; } else if(translateX<= maxDiatance){ if(isMoveScale){ startPos.x = touchs.pageX||touchs.clientX; isMoveScale=false; } var two=parseInt((touchs.pageX-startPos.x)*0.4+maxDiatance); inner.style.webkitTransform=inner.style.transform="translate3d("+two+"px,0,0)"; } else { var three=parseInt(touchs.pageX-startPos.x+downLeft); inner.style.webkitTransform=inner.style.transform="translate3d("+three+"px,0,0)"; } //if(touchs.clientX<2&&isiOS||touchs.clientX>window.innerWidth-2&&isiOS){ //左右邊界處理 ios手機bug // end(); // } } //水平 }// move end function end(){ var e=e||window.event, touchs = e.changedTouches[0], self=this, aboveY=parseInt(getTransform(self)[0]), endX=touchs.pageX||touchs.clientX, nowLeft=parseInt((endX-startPos.x)), duration=+new Date-startPos.startTime; // determine direction of swipe (true:right, false:left) // var direction = delta.x < 0; if (!isScrolling) { if(aboveY>0){ transform(self,{translate3d:'0,0,0'},260); } if(aboveY<0&&aboveY<maxDiatance){ transform(self,{translate3d:''+maxDiatance+'px,0,0'},260); } if(endX<startPos.x){//右側往左邊滑動 滑動距離大於必定 或者 滑動時間小於250毫秒 if(iNow!=aLi.length-1){ if(Math.abs(nowLeft)>parseInt(w/3)||duration<200&&Math.abs(nowLeft)>30){ iNow++; } transform(self,{translate3d:'-'+iNow*w+'px,0,0'},400); } }else{ //左邊往右側滑動 if(iNow!=0){ if(Math.abs(nowLeft)>parseInt(w/3)||duration<200&&Math.abs(nowLeft)>30){ iNow--; } transform(self,{translate3d:'-'+iNow*w+'px,0,0'},400); } } //小圓點樣式 var selects=document.getElementById("selects"), spans=selects.getElementsByTagName("span"), i=0; for(;i<spans.length;i++){ spans[i].className=''; } spans[iNow].className='on'; self.removeEventListener(touchEvent.touchmove,move,false); self.removeEventListener(touchEvent.touchend,end,false); }; } //水平 });// touchstart end } //拖拽刷新 function refreshPage(element, txtobj, fn) { var isTouch=!! ("ontouchstart" in window ); if(!isTouch) return; var startPos={}, doc=document, mydistanceY = 0, isScrolling, isDown=false, maxs2 = 0; var TransitionEnd=function () { var el = document.createElement('div'); var transEndEventNames = { WebkitTransition : 'webkitTransitionEnd', MozTransition : 'transitionend', OTransition : 'oTransitionEnd', msTransition : 'MSTransitionEnd', transition : 'transitionend' }; for (var name in transEndEventNames) { if (el.style[name] !== undefined) { return transEndEventNames[name] ; } } el=null; return false; }();; var prefix = function() { var div = document.createElement('div');//創建臨時DIV容器 var cssText = '-webkit-transition:all .1s;-moz-transition:all .1s; -Khtml-transition:all .1s; -o-transition:all .1s; -ms-transition:all .1s; transition:all .1s;'; div.style.cssText = cssText; var style = div.style, dom=''; if (style.webkitTransition) { dom ='webkit'; }else if (style.MozTransition) { dom='moz'; }else if (style.khtmlTransition) { dom='Khtml'; }else if (style.oTransition) { dom='o'; }else if (style.msTransition) { dom='ms'; } div=null; ////去掉沒必要要的數據存儲,便於垃圾回收 if(dom){////style.transition 狀況 return { dom: dom, css: '-' + dom + '-' }; }else{ return false; } }(); //參數修正 var nowTransition=prefix.dom+'Transition'; var nowTransform=prefix.dom+'Transform'; var vendors= prefix.css; if(!prefix.dom){ nowTransition='transition'; nowTransform='transform'; vendors=''; } element.addEventListener("touchstart", function(e) { var e = e || window.event, touchs = e.touches[0]; startPos={ x: touchs.pageX, y: touchs.pageY }; isDown=false; element.style[nowTransition+'Duration'] = "0s"; maxs2 = 0; isScrolling = undefined; //這個參數判斷是垂直滾動仍是水平滾動 默認0水平 doc.addEventListener("touchmove", mov2, false); doc.addEventListener("touchend", end2, false); }, false); function mov2(e) { var e = e || window.event; if (e.touches.length > 1 || e.scale && e.scale !== 1) { return } var touchs = e.changedTouches[0]; var movPos={ x:touchs.pageX , y:touchs.pageY }; if ( typeof isScrolling == 'undefined') { isScrolling = !!( isScrolling || Math.abs(movPos.x-startPos.x) < Math.abs(movPos.y-startPos.y) ); } movedistance = Math.ceil(touchs.clientY - startPos.y); if (isScrolling&&movedistance > 4) {//向下拖拽 e.preventDefault(); isDown=true; maxs2 = parseInt(movedistance * 0.2); element.style[nowTransform] = "translate3d(0," + maxs2 + "px,0)"; if (maxs2 > 35) { txtobj.innerHTML = "釋放刷新" } else { txtobj.innerHTML = "下拉刷新" } } else { isDown=false; if(!isDown){ document.removeEventListener("touchmove", mov2); document.removeEventListener("touchmove", end2); } } } function end2(e) { var e = e || window.event; var touchs = e.changedTouches[0]; if (isDown&&isScrolling&&Math.abs(touchs.clientY - startPos.y) > 5) { element.style[nowTransition]=vendors+"transform .6s cubic-bezier(0.65, 0.5, 0.12, 1)"; element.style[nowTransform] = "translate3d(0,0,0)"; var fire=false; function handler() { fire=true; fn&&fn.apply(this, arguments); element.removeEventListener(TransitionEnd, arguments.callee) } if (maxs2 > 36||txtobj.innerHTML == "釋放刷新") { element.addEventListener(TransitionEnd, handler); } setTimeout(function(){ if(!fire&&txtobj.innerHTML == "釋放刷新"){ handler(); } },660); } doc.removeEventListener("touchmove", mov2); doc.removeEventListener("touchmove", end2) } }; // var ele=document.getElementById("wraps"); //下拉元素盒子 var txtobj=document.getElementById("refreshTxt");//下拉刷新文字 refreshPage(ele,txtobj,function(){ window.location.href= window.location.href; //回調函數 也能夠ajax 刷新 }); </script> </body> </html>
上面還須要優化的 地方,touchmove時候,沒有在16.6毫秒內 進行正確的渲染 須要調用 requestAnimationFrame 進行正確的監聽渲染,後期補充;ios