手持设备点击响应速度,鼠标事件与touch事件的那些事
2016-05-26 17:12
489 查看
前言
现在一直在做移动端的开发,这次将单页应用的网页内嵌入了app,于是老大反映了一个问题:app应用点击响应慢!
我开始不以为然,于是拿着网页版的试了试,好像确实有一定延迟,于是开始了研究,最后选择了touch取代鼠标事件
但是,touch事件取代mouse事件,还是有一定问题的,据说网上问题很多,因为两者之间还是有一定差异
而且如果完全使用touch事件,对自动化测试的同事来说,他们的系统根本不支持touch事件,再者我们平时网页开发也不方便
所以,了解鼠标事件与touch事件的区别,探讨鼠标事件与touch事件的兼容也是有必要的,于是我们开始今天的学习吧
PS:这里使用zepto框架,懒得自己搞了......
事件差异
鼠标事件
首先,我们来看看鼠标事件相关吧:View Code
测试地址
http://sandbox.runjs.cn/show/7tyo48bf各位自己运行看看差异吧
简单扩展touch事件
touch没有click事件,于是有zepto搞了个tap事件,我们这里先来简单模拟一下,再看源码怎么干的1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 2 <html xmlns="http://www.w3.org/1999/xhtml"> 3 <head> 4 <title></title> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"> 6 <script id="others_zepto_10rc1" type="text/javascript" class="library" src="http://sandbox.runjs.cn/js/sandbox/other/zepto.min.js"></script> 7 </head> 8 <body> 9 <div id="d" style="position: absolute; top: 50px; left: 50px; width: 100px; height: 100px; 10 border: 1px solid black;">滑动我 11 </div> 12 </body> 13 <script type="text/javascript"> 14 var log = function (msg) { 15 console.log(msg); 16 }; 17 var d = $('body'); 18 19 var touchEvents = function (el, type, func) { 20 this.long = 400; //用于设置长点击阀值 21 this.el = el || document; 22 this.func = func || function () { }; 23 this.type = type || 'tap'; 24 this.mouseData = { 25 sTime: 0, 26 eTime: 0, 27 sX: 0, 28 eX: 0, 29 sY: 0, 30 eY: 0 31 }; 32 this.addEvent(); 33 34 }; 35 touchEvents.prototype = { 36 constructor: touchEvents, 37 addEvent: function () { 38 var scope = this; 39 this.startFn = function (e) { 40 scope.touchStart.call(scope, e); 41 }; 42 this.moveFn = function (e) { 43 scope.touchMove.call(scope, e); 44 }; 45 this.endFn = function (e) { 46 scope.touchEnd.call(scope, e); 47 }; 48 this.el.addEventListener('touchstart', this.startFn); 49 //此处可以换成这样 50 // document.addEventListener('touchmove', this.touchMove); 51 this.el.addEventListener('touchmove', this.moveFn); 52 this.el.addEventListener('touchend', this.endFn); 53 }, 54 removeEvent: function () { 55 this.el.removeEventListener('touchstart', this.touchStart); 56 this.el.removeEventListener('touchmove', this.touchMove); 57 this.el.removeEventListener('touchend', this.touchEnd); 58 }, 59 touchStart: function (e) { 60 var pos = e.changedTouches[0]; 61 this.mouseData.sTime = new Date().getTime(); 62 this.mouseData.sX = pos.pageX; 63 this.mouseData.sY = pos.pageY; 64 }, 65 touchMove: function (e) { 66 e.preventDefault(); 67 return false; 68 }, 69 touchEnd: function (e) { 70 var pos = e.changedTouches[0]; 71 this.mouseData.eTime = new Date().getTime(); 72 this.mouseData.eX = pos.pageX; 73 this.mouseData.eY = pos.pageY; 74 this.onTouchEnd(e); 75 }, 76 onTouchEnd: function (e) { 77 if (this.type == this._getDir()) { 78 this.func(e, this); 79 } 80 }, 81 _getDir: function () { 82 //时间间隔,间隔小于100都认为是快速,大于400的认为是慢速 83 var timeLag = this.mouseData.eTime - this.mouseData.sTime; 84 var dir = 'swipe'; 85 if (timeLag > this.long) dir = 'longSwipe'; 86 if (this.mouseData.sX == this.mouseData.eX && this.mouseData.sY == this.mouseData.eY) { 87 dir = 'tap'; 88 if (timeLag > this.long) dir = 'longTap'; 89 } else { 90 if (Math.abs(this.mouseData.eY - this.mouseData.sY) > Math.abs(this.mouseData.eX - this.mouseData.sX)) { 91 dir = this._getUDDir(dir); 92 } else { 93 dir = this._getLRDir(dir); 94 } 95 } 96 log(dir); 97 d.append($('<div>间隔:' + timeLag + ', 方向:' + dir + '</div>')); 98 return dir; 99 }, 100 //单独用于计算上下的 101 _getUDDir: function (dir) { 102 if (this.mouseData.eY - this.mouseData.sY > 0) dir += 'Down'; 103 if (this.mouseData.eY - this.mouseData.sY < 0) dir += 'Up'; 104 return dir; 105 }, 106 //计算左右 107 _getLRDir: function (dir) { 108 if (this.mouseData.eX - this.mouseData.sX > 0) dir += 'Right'; 109 if (this.mouseData.eX - this.mouseData.sX < 0) dir += 'Left'; 110 return dir; 111 } 112 }; 113 114 new touchEvents(d[0], 'tap', function (e) { 115 log(arguments); 116 }); 117 118 </script> 119 </html>
这个代码基本可用了,但是使用上不是很方便,我们这里就不关注了,下面我们来看看zepto的代码和兼容问题
zepto的touch与兼容
先上zepto源码,一看就知道我写的有多不行啦!按 Ctrl+C 复制代码
按 Ctrl+C 复制代码
touch对象与上面mouseData功效相同,记录一些属性
delta 用于记录两次点击的间隔,间隔短就是双击
swipeDirection 函数与_getDir _getUDDir _getLRDir 功能相似,只不过代码更为简练,并且真正的私有化了
63行代码开始,若是代码移动过便是划屏,否则就是点击,这点我也没考虑到
73行,否则就应该是点击,这里并且判断是否存在结束时间,代码比较健壮,做了双击或者快速点击的判断
开始兼容
zepto代码我自然没有资格去评说,现在我们来看看他的兼容问题PS:我这里很水,不太敢动源码,就加一个tap判断,因为也只是用了这个,具体大动手脚的事情,我们后面再做
这样做事因为,我们的项目主要是把click改成了tap事件,导致页面很多功能不可用
1 ['swipe', 'swipeLeft', 'swipeRight', 'swipeUp', 'swipeDown', 'doubleTap', 'tap', 'singleTap', 'longTap'].forEach(function (m) { 2 //兼容性方案处理,以及后期资源清理,如果为假时候,就触发点击事件 3 var isTouch = 'ontouchstart' in document.documentElement; 4 if(m === 'tap' && isTouch === false) { 5 $.fn[m] = function (callback) { return this.bind('click', callback) } 6 } else { 7 $.fn[m] = function (callback) { return this.bind(m, callback) } 8 } 9 })
我就干了这么一点点事情......
相关文章推荐
- Linux文件系统
- 在Function对象上扩展method方法
- 菜鸟对使用AIDL的一点理解
- android native 内存泄露检查(libc.debug.malloc )
- Ext JS 6开发实例(三) :主界面设计
- Ext JS 6开发实例(三) :主界面设计
- Lombok 安装、入门 - 消除冗长的 java 代码
- Ubuntu14连接MySql报错“can't connect to local mysql server through socket '/var/run/mysqld/mysqld.sock'”
- android studio很好的一个JNI 入门博文
- ps制作爆碎感的玻璃海报特效
- MyBatis学习 之 三、动态SQL语句
- HDU 4405 Aeroplane chess
- make与gmake的区别
- CentOS配置SVN服务器
- leetcode 145. Binary Tree Postorder Traversal-后续遍历|递归|非递归
- 同时也希望通过分享来增
- 同时也希望通过分享来增
- BootStrap中的table实现数据填充与分页应用小结
- 想就着这个机会
- Ext JS 6开发实例(三) :主界面设计