1 /**2 * @author accountwcx@qq.com3 * http://git.oschina.net/accountwcx/rhui4 *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,swipeDown30 * @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, $);