触摸事件是移动浏览器特有的HTML5事件,虽然click事件在pc和移动端更通用,但是在移动端会出现300ms延迟,较为影响用户体验,300ms延迟来自判断双击和长按,因为只有默认等待时间结束以确定没有后续动作发生时,才会触发click事件。所以触摸事件反应更快,体验更好。

触摸事件的类型:

为了区别触摸相关的状态改变,存在多种类型的触摸事件。可以通过检查触摸事件的 TouchEvent.type 属性来确定当前事件属于哪种类型。

注意: 在很多情况下,触摸事件和鼠标事件会同时被触发(目的是让没有对触摸设备优化的代码仍然可以在触摸设备上正常工作)。如果你使用了触摸事件,可以调用 event.preventDefault() 来阻止鼠标事件被触发。

标准的触摸事件

事件名称 描述 包含touches数组

touchstart

当用户在触摸平面上放置了一个触点时触发。事件的目标 element 将是触点位置上的那个目标 element

touchmove

当用户在触摸平面上移动触点时触发。

事件的目标 element 和这个 touchmove 事件对应的 touchstart 事件的目标 element 相同,

哪怕当 touchmove 事件触发时,触点已经移出了该 element 。

touchend

当一个触点被用户从触摸平面上移除(当用户将一个手指离开触摸平面)时触发。

当触点移出触摸平面的边界时也将触发。例如用户将手指划出屏幕边缘。

已经被从触摸平面上移除的触点,可以在 changedTouches 属性定义的 TouchList 中找到。

touchenter

当触点进入某个 element 时触发。此事件没有冒泡过程。

touchleave

当触点离开某个 element 时触发。此事件没有冒泡过程。

touchcancel

当触点由于某些原因被中断时触发。有几种可能的原因如下(具体的原因根据不同的设备和浏览器有所不同):

  • 由于某个事件取消了触摸:例如触摸过程被一个模态的弹出框打断。
  • 触点离开了文档窗口,而进入了浏览器的界面元素、插件或者其他外部内容区域。
  • 当用户产生的触点个数超过了设备支持的个数,从而导致 TouchList 中最早的 Touch 对象被取消。

触摸对象属性

Touch.identifier 返回一个可以唯一地识别和触摸平面接触的点的值. 这个值在这根手指(或触摸笔等)所引发的所有事件中保持一致, 直到它离开触摸平面.
Touch.screenX 触点相对于屏幕左边沿的的X坐标. 只读属性.
Touch.screenY 触点相对于屏幕上边沿的的Y坐标. 只读属性.
Touch.clientX 触点相对于可见视区左边沿的的X坐标. 不包括任何滚动偏移. 只读属性.
Touch.clientY 触点相对于可见视区上边沿的的Y坐标. 不包括任何滚动偏移. 只读属性.
Touch.pageX 触点相对于HTML文档左边沿的的X坐标. 当存在水平滚动的偏移时, 这个值包含了水平滚动的偏移只读属性.
Touch.pageY 触点相对于HTML文档上边沿的的Y坐标. 当存在水平滚动的偏移时, 这个值包含了垂直滚动的偏移只读属性.
Touch.radiusX 能够包围用户和触摸平面的接触面的最小椭圆的水平轴(X轴)半径. 这个值的单位和 screenX 相同. 只读属性.
Touch.force 手指挤压触摸平面的压力大小, 从0.0(没有压力)到1.0(最大压力)的浮点数. 只读属性.
Touch.radiusY 能够包围用户和触摸平面的接触面的最小椭圆的垂直轴(Y轴)半径. 这个值的单位和 screenY 相同. 只读属性.
Touch.target

当这个触点最开始被跟踪时(在 touchstart 事件中), 触点位于的HTML元素. 哪怕在触点移动过程中, 触点的位置已经离开了这个元素的有效交互区域,

或者这个元素已经被从文档中移除. 需要注意的是, 如果这个元素在触摸过程中被移除, 这个事件仍然会指向它, 但是不会再冒泡这个事件到 window 或 document 对象.

因此, 如果有元素在触摸过程中可能被移除, 最佳实践是将触摸事件的监听器绑定到这个元素本身, 防止元素被移除后, 无法再从它的上一级元素上侦测到从该元素冒泡的事件. 只读属性.

IE10+的触摸事件

IE指针事件
事件名称 描述(在触摸设备上)
MSPointerDown 触摸开始
MSPointerMove 接触点移动
MSPointerUp 触摸结束
MSPointerOver 触摸点移动到元素内,相当于mouseover
MSPointerOut 触摸点离开元素,相当于mouseout

MSPointerEvent属性

属性 描述
hwTimestamp 创建事件的时间(ms)
isPrimary 标识该指针是不是主指针
pointerId 指针的唯一ID(类似于触摸事件的标识符)
pointerType 一个整数,标识了该事件来自鼠标、手写笔还是手指
pressure 笔的压力,0-255,只有手写笔输入时才可用
rotation 0-359的整数,光标的旋转度(如果支持的话)
tiltX/tiltY 手写笔的倾斜度,只有用手写笔输入时才支持

等价事件

鼠标 触摸 键盘
mousedown touchstart keydown
mousemove touchmove keydown
mouseup touchend keyup
mouseover   focus

很显然,触摸动作序列:touchstart-touchmove-touchend和鼠标序 列:mousedown-mousemove-mouseup以及键盘序列:keydown-keypress-keyup很相似,这并不是巧合,因为这 三种交互模式都可以描述为start-move-stop。

话说回来,click要经过touchstart-touchmove-touchend流程,300ms延迟,所以需要tap事件,tap就是在同一个点轻触时间很短。

封装好的tap和longtap事件

(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)

  

HTML5触摸事件演化tap事件的更多相关文章

  1. 移动端 之 触摸事件、Tap事件和swipe事件

    触摸事件 touch是一个事件组,意思不止一个事件,是移动端滑动事件组,touchstart touchmove touchend touchcancel touchstart 当刚刚触摸屏幕的时候触 ...

  2. 移动端click时间、touch事件、tap事件

    一.click 和 tap 比较 两者都会在点击时触发,但是在手机WEB端,click会有 200~300 ms,所以请用tap代替click作为点击事件. singleTap和doubleTap 分 ...

  3. 移动端click时间、touch事件、tap事件详解

    一.click 和 tap 比较 两者都会在点击时触发,但是在手机WEB端,click会有 200~300 ms,所以请用tap代替click作为点击事件. singleTap和doubleTap 分 ...

  4. zepto学习(二)之tap事件以及tap事件点透处理

    前言 为什么通过touch可以触发click事件? touch事件的来源 PC网页上的大部分操作都是用鼠标的,即响应的是鼠标事件,包括mousedown.mouseup.mousemove和click ...

  5. zepto学习(一)之click事件和tap事件比较

    一.click 和 tap 比较 两者都会在点击时触发,但是在手机WEB端,click会有 200~300 ms,所以请用tap代替click作为点击事件. singleTap和doubleTap分别 ...

  6. 移动端为何不使用click而模拟tap事件及解决方案

    移动端click会遇到2个问题,click会有200-300ms的延迟,同时click事件的延迟响应,会出现穿透,即点击会触发非当前层的点击事件. 为什么会存在延迟? Google开发者文档中有提到: ...

  7. tap事件的原理详解

    点击事件延迟问题所在: 在移动端中,由于两次触摸是放大操作,,所以当你点击一次的时候,浏览器会等待300ms,看用户是否会进行第二次点击,如果没有的话,才会执行点击事件 为什么要解决: 随着h5游戏, ...

  8. 关于windows phone 8.1系统手机对html5触摸事件的支持情况

    近日购入一部微软Lumia 640手机,目的主要就是为了测试年中开发完成的响应式移动web项目,同时也为了将来升级win10 mobile系统.由于我们的项目目前只考虑支持IOS与Android系统, ...

  9. zepto之tap事件点透问题分析及解决方案

    点透现象出现的场景: 当A/B两个层上下z轴重叠,上层的A点击后消失或移开(这一点很重要),并且B元素本身有默认click事件(如a标签)或绑定了click事件.在这种情况下,点击A/B重叠的部分,就 ...

随机推荐

  1. Spring Boot 中使用 jpa

    本文原文版权归 CSDN Hgihness 所有,此处为转载+技术收藏,如有再转请自觉于篇头处标明原文作者及出处,这是大家对作者劳动成果的自觉尊重!! 作者:Hgihness 原文:http://bl ...

  2. 酱油 Noip2018颓废记

    也不知道写一些什么了 凑和着写写吧 最近十分的¥#&(^ --#%!*%¥^#$# Day -1 上午考了一场试 就\(TM\)考了60分 好不容易积攒起来的信心啊~~~~~~ 就这么垮了~~ ...

  3. 关于类的成员,public,private修饰符

    类的成员要:属性,方法 属性:是它本身所居有的东西,比如人的特征,也可以这样理解属性是静态状态 方法:是这些属性通过方法行为发生改变,也就是方法是动态,可以对属性进行更新 public 公共的,可以被 ...

  4. QuantLib 金融计算——数学工具之数值积分

    目录 QuantLib 金融计算--数学工具之数值积分 概述 常见积分方法 高斯积分 如果未做特别说明,文中的程序都是 Python3 代码. QuantLib 金融计算--数学工具之数值积分 载入模 ...

  5. Mac 10.12安装PDF浏览工具Foxit Reader

    说明:永久没费的跨平台PDF浏览工具. 下载: (链接: https://pan.baidu.com/s/1pLEAoXH密码: is5j)

  6. 关于c#中委托与事件的一些理解

    文章目的:作者(初学者)在学习c#的过程中,对事件.委托及其中的“object sender,EventArgs e”一直感觉理解不透,因此在网上找了一些资料,学习并整理出了该篇笔记,希望能将自己的心 ...

  7. redis有序集合类型sort set

    redis的数据类型之-有序集合 sort set和set类型一样,也是string类型元素的集合,也没有重复的元素,不同的是sort set每个元素都会关联一个权,通过权值可以有序的获取集合中的元素 ...

  8. windows下简单配置apache

    不得不做个笔记,不然每次配置都记不清楚... 详细的配置朋友这边写的很好.地址 # 对 PHP 4 LoadModule php4_module "c:/php/php4apache2.dl ...

  9. 19.Class的基本语法

    1.简介 JavaScript 语言中,生成实例对象的传统方法是通过构造函数. function Point(x, y) { this.x = x; this.y = y; } Point.proto ...

  10. JavaScript引擎理解

    JavaScript 虽然给人感觉是一个多线程执行的语言,但是其实JavaScript引擎是伪多线程,是单线程执行的, 浏览器内核:实现允许多个线程异步执行,这些线程在内核制控下相互配合以保持同步.假 ...