移動端觸屏滑動的效果其實就是圖片輪播,在PC的頁面上很好實現,綁定click和mouseover等事件來完成。但是在移動設備上,要實現這種輪播的效果,就需要用到核心的touch事件。處理touch事件能跟蹤到屏幕滑動的每根手指。
以下是四種touch事件
touchstart: //手指放到屏幕上時觸發
touchmove: //手指在屏幕上滑動式觸發
touchend: //手指離開屏幕時觸發
touchcancel: //系統取消touch事件的時候觸發,這個比較少用
每個觸摸事件被觸發后,會生成一個event對象,event對象里額外包括以下三個觸摸列表
touches: //當前屏幕上所有手指的列表
targetTouches: //當前dom元素上手指的列表,盡量使用這個代替touches
changedTouches: //涉及當前事件的手指的列表,盡量使用這個代替touches
廢話不多說,直接上代碼。
1 <!DOCTYPE html> 2 <html> 3 <head lang="en"> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=2.0, minimum-scale=1.0,user-scalable=no"> 6 <meta name="format-detection" content="email=no,telephone=no"/> 7 <title></title> 8 <style> 9 *{margin: 0;padding: 0} 10 ul li{list-style: none;} 11 /*清除浮動*/ 12 .fix { 13 zoom: 1; 14 } 15 .fix:after { 16 display: block; 17 content: 'clear'; 18 clear: both; 19 line-height: 0; 20 font-size: 0; 21 visibility: hidden; 22 } 23 #container_box{ 24 width: 100%; 25 overflow: hidden; 26 } 27 .box{width: 400%;height: 200px;overflow: hidden;} 28 .box li{ 29 float: left; 30 width: 25%; 31 height: 200px; 32 line-height: 200px; 33 font-size: 40px; 34 text-align: center; 35 cursor: pointer; 36 } 37 </style> 38 </head> 39 <body> 40 <div id="container_box"> 41 <ul id="container" class="box fix"> 42 <li style="background: #f7bac5">swipe</li> 43 </ul> 44 </div> 45 46 <script> 47 var initSwipe = { 48 init:function(id){ 49 initSwipe.addLoadEvent(initSwipe.mathFun(id)); 50 }, 51 mathFun:function(id){ 52 initSwipe.swipe(initSwipe.getById(id)); 53 }, 54 //可以加載多個onload事件 55 addLoadEvent:function(fn){ 56 var oldonload=window.onload; 57 if(typeof window.onload!='function'){ 58 window.onload=fn; 59 }else{ 60 window.onload=function(){ 61 oldonload(); 62 fn(); 63 } 64 } 65 }, 66 //解決 getElementsByClassName 兼容問題 67 getByClass:function(className,obj){// obj : 父元素 68 var obj = obj || document; 69 if (obj.getElementsByClassName) // 支持 getElementsByClassName 方法的使用 70 { 71 return obj.getElementsByClassName(className); 72 } 73 /* 不支持 getElementsByClassName 方法的使用 */ 74 var result = [];// 保存所有查找到的元素的數組結構 75 // 查找出 obj 對象后代所有元素 76 var tags = obj.getElementsByTagName("*"); 77 for (var i = 0, len = tags.length; i < len; i++) {// 遍歷每個元素 78 var classNames = tags[i].className.split(" ");// 獲取到當前遍歷元素所使用的所有類名 79 for (var j = 0, l = classNames.length; j < l; j++) {// 遍歷當前元素的每個類名 80 if ( classNames[j] === className ) { // 說明當前遍歷到的元素使用過要查找的類名 81 result.push(tags[i]); 82 break; 83 } 84 } 85 } 86 // 返回結果集 87 return result; 88 }, 89 getById:function(idSelect,obj){ 90 var obj = obj || document; 91 return obj.getElementById(idSelect); 92 }, 93 getByTagName:function(TagName,obj){ 94 var obj = obj || document; 95 return obj.getElementsByTagName(TagName); 96 }, 97 // 事件綁定 98 bindHandler:function(elem, type, handler) { 99 if (window.addEventListener) {// 標准瀏覽器 100 return elem.addEventListener(type, handler, false); 101 } else if (window.attachEvent) {// IE瀏覽器 102 return elem.attachEvent("on" + type, handler); 103 } 104 }, 105 // 事件解除 106 removeHandler:function(elem, type, handler) { 107 if (window.removeEventListener) {// 標准瀏覽器108 109 elem.removeEventListener(type, handler, false);110 111 } else if (window.detachEvent) {// IE瀏覽器112 113 elem.detachEvent("on" + type, handler);114 115 } 116 }, 117 //滑動事件 118 swipe:function(container){ 119 var container = container; 120 var index = 1; 121 var flag = false;//判斷是否發生滑動事件 122 var swipe_distance = 30;//移動30px之后才認為swipe事件 123 var swipe_time = 500;//swipe最大經歷時間 124 var point_start,point_end, time_start,time_end; 125 // 判斷是PC還是移動設備 126 var startEvt,moveEvt,endEvt; 127 if('ontouchstart' in window){ 128 startEvt = 'touchstart'; 129 moveEvt = 'touchmove'; 130 endEvt = 'touchend'; 131 }else{ 132 startEvt = 'mousedown'; 133 moveEvt = 'mousemove'; 134 endEvt = 'mouseup'; 135 } 136 // 獲取touch的點(兼容mouse事件) 137 var getTouchPos = function(e){ 138 var touches = e.touches; 139 if(touches && touches[0]){ 140 return{ 141 x: touches[0].clientX, 142 y: touches[0].clientY 143 }; 144 } 145 return {x: e.clientX,y: e.clientY}; 146 }; 147 // 計算兩點之間的距離 148 var getDist = function(p1,p2){ 149 if(!p1 || !p2){return 0;} 150 return Math.sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)); 151 }; 152 // 計算兩點之間的角度 153 var getAngle = function(p1,p2){ 154 var r = Math.atan2(p2.y-p1.y,p2.x-p1.x);//這里獲取的是幅度 155 var a = r*180 / Math.PI;//幅度轉角度 156 return a; 157 }; 158 // 獲取swipe方向 159 var getSwipeDirection = function(p2,p1){ 160 var dx = p2.x-p1.x; 161 var dy = -p2.y+p1.y; 162 var angle = Math.atan2(dy,dx)*180/Math.PI; 163 if(angle < 45 && angle > -45){return 'right';} 164 if(angle >= 45 && angle < 135){return 'top';} 165 if(angle >= 135 || angle < -135){return 'left';} 166 if(angle >= -135 && angle <= -45){return 'bottom';} 167 }; 168 // 記錄touchstart開始時間和位置 169 var startEvtHandler = function(e){ 170 flag = false; 171 var date = new Date(); 172 var touches = e.touches; 173 if(!touches || touches.length==1){//touches為空,代表鼠標點擊 174 point_start = getTouchPos(e); 175 time_start = date.getTime(); 176 } 177 }; 178 // touchmove 179 var moveEvtHandler = function(e){ 180 point_end = getTouchPos(e); 181 flag = true; 182 return false; 183 }; 184 // touchend的touches和targetTouch沒有對象,只有changeTouches才有 185 var endEvtHandler = function(e){ 186 var date = new Date(); 187 time_end = date.getTime(); 188 //距離和時間都符合 189 if(getDist(point_start,point_end)>swipe_distance && time_end-time_start<swipe_time){ 190 var dir = getSwipeDirection(point_end,point_start); 191 var objHtml = initSwipe.getByTagName('li',container)[0]; 192 if(dir=='left' && flag == true){//向左滑 193 objHtml.innerHTML = 'swipe left'; 194 }else if(dir=='right' && flag == true){//向右滑 195 objHtml.innerHTML = 'swipe right'; 196 }else if(dir=='top' && flag == true){//向上滑 197 objHtml.innerHTML = 'swipe top'; 198 }else if(dir=='bottom' && flag == true){//向下滑 199 objHtml.innerHTML = 'swipe bottom'; 200 } 201 } 202 flag = false; 203 }; 204 initSwipe.bindHandler(container,startEvt,startEvtHandler); 205 initSwipe.bindHandler(container,moveEvt,moveEvtHandler); 206 initSwipe.bindHandler(container,endEvt,endEvtHandler); 207 } 208 }; 209 initSwipe.init('container'); 210 </script> 211 </body> 212 </html>
本人測試兼容IE8+,
container