触摸事件是移动浏览器特有的HTML5事件,虽然click事件在pc和移动端更通用,但是在移动端会出现300ms延迟,较为影响用户体验,300ms延迟来自判断双击和长按,因为只有默认等待时间结束以确定没有后续动作发生时,才会触发click事件。所以触摸事件反应更快,体验更好。
触摸事件的类型:
为了区别触摸相关的状态改变,存在多种类型的触摸事件。可以通过检查触摸事件的 TouchEvent.type 属性来确定当前事件属于哪种类型。
注意: 在很多情况下,触摸事件和鼠标事件会同时被触发(目的是让没有对触摸设备优化的代码仍然可以在触摸设备上正常工作)。如果你使用了触摸事件,可以调用 event.preventDefault() 来阻止鼠标事件被触发。
事件名称 | 描述 |
touchstart | 当用户在触摸平面上放置了一个触点时触发。事件的目标 element 将是触点位置上的那个目标 element |
touchmove | 当用户在触摸平面上移动触点时触发。事件的目标 element 和这个 touchmove 事件对应的 touchstart 事件的目标 element 相同,哪怕当 touchmove 事件触发时,触点已经移出了该 element 。 |
touchend | 当一个触点被用户从触摸平面上移除(当用户将一个手指离开触摸平面)时触发。 当触点移出触摸平面的边界时也将触发。例如用户将手指划出屏幕边缘。 已经被从触摸平面上移除的触点,可以在 changedTouches 属性定义的 TouchList 中找到。 |
touchenter | 当触点进入某个 element 时触发。此事件没有冒泡过程。 |
touchleave | 当触点离开某个 element 时触发。此事件没有冒泡过程。 |
touchcancel | 当触点由于某些原因被中断时触发。有几种可能的原因如下(具体的原因根据不同的设备和浏览器有所不同):
由于某个事件取消了触摸:例如触摸过程被一个模态的弹出框打断。 触点离开了文档窗口,而进入了浏览器的界面元素、插件或者其他外部内容区域。 当用户产生的触点个数超过了设备支持的个数,从而导致 TouchList 中最早的 Touch 对象被取消。 |
IE10+的触摸事件
事件名称 | 描述 |
MSPointerDown | 触摸开始 |
MSPointerMove | 接触点移动 |
MSPointerUp | 触摸结束 |
MSPointerOver | 触摸点移动到元素内,相当于mouseover |
MSPointerOut | 触摸点离开元素,相当于mouseout |
等价事件
鼠标 | 触摸 | 键盘 |
mousedown | touchstart | keydown |
mousemove | touchmove | keydown |
mouseup | touchend | keyup |
mouseover | mouseover | focus |
MSPointerOut | 触摸点离开元素,相当于mouseout |
很显然,触摸动作序列:touchstart-touchmove-touchend和鼠标序 列:mousedown-mousemove-mouseup以及键盘序列:keydown-keypress-keyup很相似,这并不是巧合,因为这 三种交互模式都可以描述为start-move-stop。
话说回来,click要经过touchstart-touchmove-touchend流程,300ms延迟,所以需要tap事件,tap就是在同一个点轻触时间很短。
封装好的tap和longtap事件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
(function() { var TOUCHSTART, TOUCHEND; if (typeof(window.ontouchstart) != 'undefined') { TOUCHSTART = 'touchstart'; TOUCHEND = 'touchend'; TOUCHMOVE='touchmove'; } else if (typeof(window.onmspointerdown) != 'undefined') { TOUCHSTART = 'MSPointerDown'; TOUCHEND = 'MSPointerUp'; TOUCHMOVE='MSPointerMove'; } else { TOUCHSTART = 'mousedown'; TOUCHEND = 'mouseup'; TOUCHMOVE = 'mousemove'; } function NodeTouch(node) { this._node = node; } function tap(node,callback,scope) { node.addEventListener(TOUCHSTART, function(e) { x = e.touches[0].pageX; y = e.touches[0].pageY; }); node.addEventListener(TOUCHEND, function(e) { e.stopPropagation(); e.preventDefault(); var curx = e.changedTouches[0].pageX; var cury = e.changedTouches[0].pageY; if (Math.abs(curx - x) < 6 && Math.abs(cury - y) < 6) { callback.apply(scope, arguments); } }); } function longTap(node,callback,scope) { var x,y,startTime=0,endTime=0,in_dis=false; node.addEventListener(TOUCHSTART, function(e) { x = e.touches[0].pageX; y = e.touches[0].pageY; startTime=(new Date()).getTime(); }); node.addEventListener(TOUCHEND, function(e) { e.stopPropagation(); e.preventDefault(); var curx = e.changedTouches[0].pageX; var cury = e.changedTouches[0].pageY; if (Math.abs(curx - x) < 6 && Math.abs(cury - y) < 6) { in_dis=true; }else{ in_dis=false; } endTime=(new Date()).getTime(); if (endTime - startTime > 300 && in_dis) { callback.apply(scope, arguments); } }); } NodeTouch.prototype.on = function(evt, callback, scope) { var scopeObj; var x,y; if (!scope) { scopeObj = this._node; } else { scopeObj = scope; } if (evt === 'tap') { tap(this._node,callback,scope); } else if(evt === 'longtap'){ longTap(this._node,callback,scope); } else { this._node.addEventListener(evt, function() { callback.apply(scope, arguments); }); } return this; } window.$ = function(selector) { var node = document.querySelector(selector); if (node) { return new NodeTouch(node); } else { return null; } } })(); var box=$("#box"); box.on("longtap",function(){ console.log("你已经长按了"); },box) |
ps: 原文链接
原文地址:https://www.cnblogs.com/chinatrump/p/11597071.html