什么是touch事件?
随着智能手机和平板电脑的普及, 越来越多的人用移动设备浏览网页,我们平时在pc浏览器上用的鼠标事件,比如:click, mouseover等, 已经无法满足移动设备触摸屏的特点。
触摸时代的到来,离不开触摸事件 touch事件用于移动端,可响应用户手指(或触控笔)对屏幕或者触控板操作,给基于触控操作,给基于触控的用户界面提供可靠的支持。
手机中click事件有300ms的延迟
移动端有个两次连续“轻触”是“放大”的操作,在你第一次被“轻触”后,浏览器需要先等一段时间,若有“连续的第二次轻触”,则进行“放大”操作,否则就执行click事件,这就导致了移动端所谓的300ms
click延迟,
连续快速双击元素对象时会触发此事件。
移动端由于双击缩放的存在,pc端的dblclick事件也失效了。
移动端浏览器都引入了触摸(touch)事件。
最基本4个事件:
touchcancel : 如电话接入或者弹出信息,会取消当前的touch操作,即触发touchcancel。一般会在touchcancel时暂停游戏、存档等操作。
preventDefault()事件可以阻止滚动。
如果你使用了触摸事件,可以调用 event.preventDefault()来阻止鼠标事件被触发。
当用户手指触摸到的触摸屏的时候触发。
点击我!
当用户在触摸屏上移动触点(手指)的时候,触发这个事件。一定是先要触发touchstart事件,再有可能触发 touchmove 事件。
注意: 即使手指移出了 原来的target 元素,则 touchmove 仍然会被一直触发,而且 target 仍然是原来的 target 元素。
点击我!
当用户的手指抬起的时候,会触发 touchend 事件。如何用户的手指从触屏设备的边缘移出了触屏设备,也会触发 touchend 事件。
点击我!
当触点由于某些原因被中断时触发。
几种可能的原因:
touchcancel 事件一般用于保存现场数据。比如:正在玩游戏,如果发生了 。
touchcancel事件,则应该把游戏当前状态相关的一些数据保存起来。
TouchEvent :是描述手指在触摸平面(触摸屏、触摸板等)的状态变化的事件。这类事件用于描述一个或多个触点,使开发者可以检测触点的移动,触点的增加和减少,等等。
每个Touch 对象代表一个触点; 每个触点都由其位置,大小,形状,压力大小,和目标 组成。
TouchList 对象代表多个触点的一个列表。
举例来讲, 如果一个用户用三根手指接触屏幕, 与之相关的TouchList 对每根手指都会生成一个Touch对象, 共计 3 个(touches 、targetTouches、changedTouches)。
一个TouchList对象,包含当前所有屏幕上的触点的Touch对象,该属性不一定是当前元素的touchstart事件触发。(单触点)
也是一个TouchList对象,包含从当前元素touchstart事件触发的触点Touch对象。(多触点)
一个TouchList对象,对于touchstart事件, 这个TouchList对象列出在此次事件中新增加的触点。对于touchmove事件,列出和上一次事件相比较,发生了变化的触点。对于touchend,列出离开触摸平面的触点。这些触点已经不再接触手指。(多触点)
touches和targetTouches只存储接触屏幕的触点,touchend时,touches和targetTouches是个空数组,所以要获取触点最后离开的状态要使用changedTouches。
放1个手指在div上
先放1个手指在其他地方,然后再放1个手指在div上
clientX:触摸目标在视口中的x坐标。(不计算滚动条)
clientY:触摸目标在视口中的y坐标。
identifier:标识触摸的唯一ID。
pageX:触摸目标在页面中的x坐标。(包含滚动条)
pageY:触摸目标在页面中的y坐标。
screenX:触摸目标在屏幕中的x坐标。
screenY:触摸目标在屏幕中的y坐标。
target:触目的DOM节点目标。
/*
* 参数说明
* el:绑定点击事件的对象
* callback: 点击事件触发后 要执行的代码
*/
//避免命名冲突
var myTouch = {
//点击事件:首先有 touchstart 事件,不能移动 touchmove,touchend结束与touchstar开始时间差,小于150ms。
tap: function (el, callback) {
var isMove = false; //是否执行了touchmove事件
var startTime = 0; //重置记录按下时的当前时间,默认为 0;
// 传的 el 必须是对象
if (typeof el === "object") {
el.addEventListener("touchstart", function () {
//按下时记录当前时间戳
startTime = new Date() * 1;
});
el.addEventListener("touchmove", function () {
isMove = true;
});
el.addEventListener("touchend", function (ev) {
//触点离开屏幕时当前的时间
var endTime = new Date() * 1;
//触点抬起时判断是否是点击的事件。
//结束时间 与 开始时间小于150ms;并且没有移动事件时为点击事件。
if((endTime - startTime) < 150 && !isMove){
//执行回调函数
//callback 是否有值 && 执行函数
callback && callback(ev,el);
}
//记录的变量恢复初始值
startTime = 0;
isMove = false;
})
}
}
}
/**
* @param {object} el:添加事件的DOM元素
* @param {function} callback:单击事件执行的回调函数
* @function [封装滑动事件:左滑,右滑,上滑,下滑]
*/
swipe: function(el, dir, callback) {
var startPoint = null, // 起始点坐标
endPoint = null,
distance = 30;
// 滑动基于touchstart touchmove touchend
if (typeof el === 'object') {
// 监听事件
el.addEventListener('touchstart', function(e) {
var touchPoint = e.touches[0]; // touch对象
// 记录起始点坐标 startPoint
startPoint = {
x: touchPoint.clientX,
y: touchPoint.clientY
};
});
el.addEventListener('touchmove', function(e) {
// 记录移动后的坐标,前提是有startPoint
if (startPoint) {
var touchPoint = e.touches[0]; // touch对象
endPoint = {
x: touchPoint.clientX,
y: touchPoint.clientY
};
}
});
el.addEventListener('touchend', function() {
// console.log(startPoint, endPoint);
// 调用计算滑动方向函数
if (startPoint && endPoint && swipeDirection(startPoint, endPoint) === dir) {
callback && callback();
}
clearSwipe();
});
// 判断滑动方法
/*
计算起始与结束的差值
判断滑动是水平还是垂直
*/
function swipeDirection(start, end) {
var diffX = start.x - end.x; // 水平差值
var diffY = start.y - end.y; // 垂直差值
// 求绝对值
var absX = Math.abs(diffX);
var absY = Math.abs(diffY);
var direction = '';
// 判断是否算滑动 差值 > 30
if (absX > distance || absY > distance) {
// 判断水平还是垂直
if (absX > absY) { // 水平滑动
direction = diffX > 0 ? 'swipeLeft' : 'swipeRight';
} else {
direction = diffY > 0 ? 'swipeUp' : 'swipeDown';
}
}
return direction;
}
/*
* @function [清除数据]
*/
function clearSwipe() {
startPoint = null;
endPoint = null;
}
}
}