移動H5開發中經常用到滑動效果(頁面上移、下移、向左滑動、向右滑動等),瀏覽器並沒有內置swipe事件,可以通過touch事件(touchstart、touchmove和touchend)模擬swipe效果。jQuery mobile和zeptojs提供了swipe事件。jquery mobile只有swipeLeft和swipeRight,zeptojs提供了完整的tap和swipe事件。
1 /** 2 * @author accountwcx@qq.com 3 * http://git.oschina.net/accountwcx/rhui 4 * 5 * swipe事件,包括swipeLeft、swipeRight、swipeUp、swipeDown。 6 * 調用方法 7 * Rhui.mobile.swipeLeft(el, callback, options) 8 * Rhui.mobile.swipeRight(el, callback, options) 9 * Rhui.mobile.swipeUp(el, callback, options) 10 * Rhui.mobile.swipeDown(el, callback, options) 11 * 如果使用jQuery,調用方法 12 * $(el).rhuiSwipe('swipeLeft', callback, options); 13 * $(el).rhuiSwipe('swipeRight', callback, options); 14 * $(el).rhuiSwipe('swipeUp', callback, options); 15 * $(el).rhuiSwipe('swipeDown', callback, options); 16 */ 17 (function(window, $){ 18 var Rhui = window.Rhui || {}; 19 window.Rhui = Rhui; 20 Rhui.mobile = (function(){ 21 var touch = { 22 distance: 30, //滑動距離,超過該距離觸發swipe事件,單位像素。 23 duration: 1000 //滑動時長,超過該時間不觸發swipe,單位毫秒。 24 }; 25 26 /** 27 * 綁定事件 28 * @param el 觸發事件的元素 29 * @param swipe 事件名稱,可選值為swipeLeft,swipeRight,swipeUp,swipeDown 30 * @param callback 事件回調函數 31 * @param isStopPropagation 是否停止冒泡,true為停止冒泡 32 * @param isPreventDefault 是否阻止默認事件,true為阻止默認事件 33 * @param triggerOnMove swipe事件有兩種觸發方式,一種是在touchmove過程中,只要滿足滑動距離條件即觸發。 34 * 一種是在touchend中,進入滑動距離判斷,如果滿足滑動距離觸發。 35 * 默認是在touchend中觸發。 36 */ 37 function bindSwipe(el, swipe, callback, triggerOnMove, isStopPropagation, isPreventDefault){ 38 var startPoint, endPoint, timer; 39 40 /** 41 * 計算滑動方向 42 * 首先根據x方向和y方向滑動的長度決定觸發x方向還是y方向的事件。 43 * 然后再判斷具體的滑動方向。 44 * 如果滑動距離不夠長,不判斷方向。 45 */ 46 function swipeDirection(x1, y1, x2, y2){ 47 var diffX = x1 - x2, 48 diffY = y1 - y2, 49 absX = Math.abs(diffX), 50 absY = Math.abs(diffY), 51 swipe; 52 53 if(absX >= absY){ 54 if(absX >= touch.distance){ 55 swipe = diffX > 0 ? 'swipeLeft' : 'swipeRight'; 56 } 57 }else{ 58 if(absY >= touch.distance){ 59 swipe = diffY > 0 ? 'swipeUp' : 'swipeDown'; 60 } 61 } 62 63 return swipe; 64 } 65 66 // 清除本次滑動數據 67 function clearSwipe(){ 68 startPoint = undefined; 69 endPoint = undefined; 70 71 if(timer !== undefined){ 72 clearTimeout(timer); 73 timer = undefined; 74 } 75 } 76 77 /** 78 * 判斷是否符合條件,如果符合條件就執行swipe事件 79 * @param el {HTMLElement} 元素 80 * @param event {Event} Touch原始事件 81 * @param return 如果執行了事件,就返回true。 82 */ 83 function execSwipe(el, event){ 84 if(startPoint && endPoint && swipeDirection(startPoint.x, startPoint.y, endPoint.x, endPoint.y) === swipe){ 85 callback.call(el, event); 86 return true; 87 } 88 } 89 90 el.addEventListener('touchstart', function(event){ 91 var self = this, touchPoint = event.touches[0]; 92 93 if(isStopPropagation){ 94 event.stopPropagation(); 95 } 96 97 if(isPreventDefault){ 98 event.preventDefault(); 99 } 100 101 startPoint = { 102 x: Math.floor(touchPoint.clientX), 103 y: Math.floor(touchPoint.clientY) 104 }; 105 106 timer = setTimeout(function(){ 107 //如果超時,清空本次touch數據 108 clearSwipe(); 109 }, touch.duration); 110 }); 111 112 el.addEventListener('touchmove', function(event){ 113 var self = this, touchPoint = event.touches[0]; 114 115 if(isStopPropagation){ 116 event.stopPropagation(); 117 } 118 119 if(isPreventDefault){ 120 event.preventDefault(); 121 } 122 123 if(startPoint){ 124 endPoint = { 125 x: Math.floor(touchPoint.clientX), 126 y: Math.floor(touchPoint.clientY) 127 }; 128 129 //執行swipe事件判斷,是否符合觸發事件 130 if(triggerOnMove){ 131 if(execSwipe(self, event)){ 132 clearSwipe(); 133 } 134 } 135 } 136 }); 137 138 el.addEventListener('touchend', function(event){ 139 if(isStopPropagation){ 140 event.stopPropagation(); 141 } 142 143 if(isPreventDefault){ 144 event.preventDefault(); 145 } 146 147 execSwipe(self, event); 148 //清除本次touch數據 149 clearSwipe(); 150 }); 151 } 152 153 /** 154 * @param el {HTMLElement} HTML元素 155 * @param callback {Function} 事件回調函數 156 * @param options {Object} 可選參數 157 * isStopPropagation {Boolean} 是否停止冒泡,true為停止冒泡 158 * isPreventDefault {Boolean} 是否阻止默認事件,true為阻止默認事件 159 * triggerOnMove {Boolean} 160 * swipe事件有兩種觸發方式,一種是在touchmove過程中,只要滿足滑動距離條件即觸發。 161 * 一種是在touchend中,進入滑動距離判斷,如果滿足滑動距離觸發。 162 * 默認值為false,在touchend中觸發。 163 */ 164 touch.swipeLeft = function(el, callback, options){ 165 if(options){ 166 bindSwipe(el, 'swipeLeft', callback, options.triggerOnMove, options.isStopPropagation, options.isPreventDefault); 167 }else{ 168 bindSwipe(el, 'swipeLeft', callback); 169 } 170 171 }; 172 173 touch.swipeRight = function(el, callback, options){ 174 if(options){ 175 bindSwipe(el, 'swipeRight', callback, options.triggerOnMove, options.isStopPropagation, options.isPreventDefault); 176 }else{ 177 bindSwipe(el, 'swipeRight', callback); 178 } 179 }; 180 181 touch.swipeUp = function(el, callback, options){ 182 if(options){ 183 bindSwipe(el, 'swipeUp', callback, options.triggerOnMove, options.isStopPropagation, options.isPreventDefault); 184 }else{ 185 bindSwipe(el, 'swipeUp', callback); 186 } 187 }; 188 189 touch.swipeDown = function(el, callback, options){ 190 if(options){ 191 bindSwipe(el, 'swipeDown', callback, options.triggerOnMove, options.isStopPropagation, options.isPreventDefault); 192 }else{ 193 bindSwipe(el, 'swipeDown', callback); 194 } 195 }; 196 197 return touch; 198 })(); 199 200 // 注冊jquery方法 201 if($ && $.fn){ 202 $.fn.extend({ 203 /** 204 * 模擬touch swipe事件,支持鏈式調用。 205 * @param name {String} swipe事件名稱,值有swipLeft、swipeRight、swipeUp、swipeDown。 206 * @param callback {Function} swipe事件回調函數 207 * @param opts {Object} 可選參數 208 * isStopPropagation {Boolean} 是否停止冒泡,true為停止冒泡 209 * isPreventDefault {Boolean} 是否阻止默認事件,true為阻止默認事件 210 * triggerOnMove {Boolean} swipe事件有兩種觸發方式,一種是在touchmove過程中,只要滿足滑動距離條件即觸發。 211 * 一種是在touchend中,進入滑動距離判斷,如果滿足滑動距離觸發。 212 * 默認值為false,在touchend中觸發。 213 */ 214 rhuiSwipe: function(name, callback, opts){ 215 var fnSwipe = Rhui.mobile[name]; 216 217 if(this.length > 0 && fnSwipe){ 218 this.each(function(){ 219 fnSwipe(this, callback, opts); 220 }); 221 } 222 223 return this; 224 } 225 }); 226 } 227 })(window, $);
使用實例:
<style type="text/css">
.test{
width: 400px;
height: 400px;
}
</style>
<div id="div1" class="test"></div>
<div class="test"></div>
<script type="text/javascript">
Rhui.mobile.swipeUp(document.getElementById('div1'), function(event){
console.log(event);
}, {
// 可選參數
isStopPropagation: true,
isPreventDefault: true,
triggerOnMove: true
});
$('.test').rhuiSwipe('swipeLeft', function(event){
console.log(event);
}, {
// 可選參數
isStopPropagation: true,
isPreventDefault: true,
triggerOnMove: true
});
</script>
實例展示:
<style type="text/css"> .test{ width: 400px; height: 400px; } </style> <div id="div1" class="test"></div> <div class="test"></div> <script type="text/javascript"> Rhui.mobile.swipeUp(document.getElementById('div1'), function(event){ console.log(event); }, { // 可選參數 isStopPropagation: true, isPreventDefault: true, triggerOnMove: true }); $('.test').rhuiSwipe('swipeLeft', function(event){ console.log(event); }, { // 可選參數 isStopPropagation: true, isPreventDefault: true, triggerOnMove: true }); </script>
zeptojs touch事件
zeptojs也提供了滑動事件,該滑動事件需要引用額外的touch.js。
| 事件 | 描述 |
|---|---|
| tap | 類似PC端瀏覽器的鼠標點擊事件,由於移動瀏覽器點擊事件有延遲,tap提供了無延遲的點擊效果。 |
| singleTap | 效果和tap一樣 |
| doubleTap | 類似PC端瀏覽器的鼠標雙擊事件 |
| longTap | 長按事件,在元素上長按超過0.75秒觸發。有些瀏覽器有默認的長按事件,可能會被覆蓋。 |
| swipe | 滑動事件,該事件不考慮滑動方向。 |
| swipeLeft | 向左滑動 |
| swipeRight | 向右滑動 |
| swipeUp | 向上滑動 |
| swipeDown | 向下滑動 |
實例展示:
1 <style>.delete { display: none; }</style> 2 3 <ul id=items> 4 <li>List item 1 <span class=delete>DELETE</span></li> 5 <li>List item 2 <span class=delete>DELETE</span></li> 6 </ul> 7 8 <script> 9 // show delete buttons on swipe 10 $('#items li').swipe(function(){ 11 $('.delete').hide() 12 $('.delete', this).show() 13 }) 14 15 // delete row on tapping delete button 16 $('.delete').tap(function(){ 17 $(this).parent('li').remove() 18 }) 19 </script>
本文摘自死神的喪鍾 http://blog.csdn.net/accountwcx/article/details/49334091
