移动端 之 触摸事件、Tap事件和swipe事件
触摸事件
touch是一个事件组,意思不止一个事件,是移动端滑动事件组,touchstart touchmove touchend touchcancel
touchstart 当刚刚触摸屏幕的时候触发
touchmove 在屏幕上来回的滑动的时候触发
touchend 离开屏幕的时候触发
touchcancel 被迫终止触摸的时候触发 (例如:来电 消息弹窗)
<div class="box"></div>
<script>
var box = document.querySelector('.box');
/*1 touchstart 当刚刚触摸屏幕的时候触发 */
box.addEventListener('touchstart', function (e) {
console.log('touchstart');
console.log(e);
});
/*2 touchmove 在屏幕上来回的滑动的时候触发*/
box.addEventListener('touchmove', function (e) {
console.log('touchmove');
});
/*3 touchend 离开屏幕的时候触发*/
box.addEventListener('touchend', function (e) {
console.log('touchend');
console.log(e);
}); /*获取触摸点坐标*/
/*1. clientX/Y 记录的是基于视口的坐标*/
/*2. pageX/Y 记录的是基于页面的坐标*/
/*3. screenX/Y 记录的是基于屏幕的坐标*/
/*不管什么坐标都可以 需要的是位置的改变 */
</script>
Tap事件
在移动端使用click事件时,会存在大概200~300ms的延迟,如果不自己封装tap事件,那么就需要引入fastclick.js文件。
singleTap事件
tap事件是依据touches组来封装的:
自己封装的tap事件:
var tap = function(dom,callback){
//判断是否滑动过
var isMove = false;
//记录响应的速度
var time = 0;
dom.addEventListener('touchstart',function(e){
time = Date.now();
console.log(e);
});
dom.addEventListener('touchmove',function(e){
isMove = true;
});
dom.addEventListener('touchend',function(e){
var respondTime = Date.now() - time;
/*tap*/
if(!isMove && respondTime < 150){
/*满足条件*/
callback && callback();
}
//重置
isMove = false;
});
}
var box = document.querySelector('.box');
tap(box, function(){
// your code...
console.log('tap触发了');
});
HTMLElement.prototype.myTap = HTMLElement.prototype.myTap || function (callBack) {
// myTapStart --- touchstart事件时间戳
// myTapEnd --- 获取touchend事件时间戳
// timeTap --- myTapStart - myTapEnd <= timeTap 时,被认为触发 tap 事件
let myTapStart = 0,
myTapEnd = 0,
timeTap = 300;
// 监听 touchstart 事件
this.addEventListener('touchstart', function (e) {
// 获取touchstart事件的时间戳
myTapStart = e.timeStamp;
// changedTouchs 是事件对象 TouchEvent 上面的属性,上面存储了一个当前操作的信息。
let point = e.changedTouches[0];
this.strX = point.pageX;
this.strY = point.pageY;
// 锁死 touchmove 事件
this.isMove = false;
}, false);
// 监听 touchmove 事件
this.addEventListener('touchmove', function (e) {
let point = e.changedTouches[0];
let changeX = point.pageX - this.strX;
let changeY = point.pageY - this.strY;
if (Math.abs(changeX) > 10 || Math.abs(changeY) > 10) {
this.isMove = true;
}
}, false);
// 监听 touchend 事件
this.addEventListener('touchend', function (e) {
// 获取 touchend 事件的时间戳
myTapEnd = e.timeStamp;
const isTimeTap = myTapEnd - myTapStart;
if (!this.isMove && isTimeTap <= timeTap) {
callBack();
}
}, false);
};
let box = document.querySelector(".box");
box.myTap(function () {
// your code...
console.log("单击事件myTap");
});
doubleTap事件
HTMLElement.prototype.doubleTap = HTMLElement.prototype.doubleTap || function (callBack) {
// isTouchEnd
// lastTime
// lastTx lastTy --- 合理范围内的误差
// firstTouchEnd --- 第一次 触发 touchend 事件
// body --- iphone os
// dTapTimer --- 定时器
// startTx startTy --- 获取 touchstart 的位置
// startTime --- 兼容 iphone os
let isTouchEnd = false,
lastTime = 0,
lastTx = null,
lastTy = null,
firstTouchEnd = true,
body = document.body,
dTapTimer, startTx, startTy, startTime;
// 监听 touchstart
this.addEventListener('touchstart', function (e) {
// 清除定时器s
if (dTapTimer) {
console.log('dTapTimer');
clearTimeout(dTapTimer);
dTapTimer = null;
}
// 获取 touchstart 的位置
const touches = e.touches[0];
startTx = touches.clientX;
startTy = touches.clientY;
}, false);
// 监听 touchend
this.addEventListener('touchend', function (e) {
const touches = e.changedTouches[0],
endTx = touches.clientX,
endTy = touches.clientY,
now = Date.now(),
duration = now - lastTime;
// 首先要确保能触发单次的 tap 事件
if (Math.abs(startTx - endTx) < 6 && Math.abs(startTx - endTx) < 6) {
console.log('单次点击的 touchstart 的位置和 touchend 的位置允许 6px 的误差');
// 两次 tap 的间隔确保在 500 毫秒以内
if (duration < 501) {
// 本次的 tap 位置和上一次的 tap 的位置允许一定范围内的误差
if (lastTx !== null && Math.abs(lastTx - endTx) < 45 && lastTy !== null && Math.abs(lastTy - endTy) < 45) {
firstTouchEnd = true;
lastTx = lastTy = null;
callBack()
}
} else {
lastTx = endTx;
lastTy = endTy;
}
} else {
firstTouchEnd = true;
lastTx = lastTy = null;
}
// 获取上一次点击的时间戳
lastTime = now;
}, false);
// 在 iOS 的 safari 上手指敲击屏幕的速度过快,
// 有一定的几率会导致第二次不会响应 touchstart 和 touchend 事件
// 同时手指长时间的touch不会触发click
if (navigator.userAgent.toLowerCase().indexOf('iphone os')) {
console.log('iphone os');
body.addEventListener('touchstart', function (e) {
startTime = Date.now();
}, true);
body.addEventListener('touchend', function (e) {
let noLongTap = Date.now() - startTime < 501;
if (firstTouchEnd) {
firstTouchEnd = false;
if (noLongTap && e.target === this) {
dTapTimer = setTimeout(function () {
// 永远不会执行setTimeout里面的代码,因为在 click 中清除了 dTapTimer
firstTouchEnd = true;
lastTx = lastTy = null;
console.log('fire double tap event at iphone os');
callBack()
}, 400);
}
} else {
firstTouchEnd = true;
}
}, true);
// iOS 上手指多次敲击屏幕时的速度过快不会触发 click 事件
body.addEventListener('click', function (e) {
if (dTapTimer) {
clearTimeout(dTapTimer);
dTapTimer = null;
firstTouchEnd = true;
}
}, false);
}
}
let box = document.querySelector('.box')
box.doubleTap(function() {
console.log('doubleTap 触发了')
})
longTap事件
<script>
HTMLElement.prototype.longTap = HTMLElement.prototype.longTap || function (callBack) {
let startTx, startTy, lTapTimer;
this.addEventListener('touchstart', function (e) {
// 清除定时器
if (lTapTimer) {
clearTimeout(lTapTimer);
lTapTimer = null;
}
// 获取 touchstart 位置
let touches = e.touches[0];
startTx = touches.clientX;
startTy = touches.clientY; lTapTimer = setTimeout(function () {
callBack()
console.log('fire long tap event');
}, 1000); e.preventDefault();
}, false); this.addEventListener('touchmove', function (e) {
// 获取 touchmove 位置
let touches = e.touches[0],
endTx = touches.clientX,
endTy = touches.clientY;
// 定时器存在 并且 发生了 touchmove 清除定时器
if (lTapTimer && (Math.abs(endTx - startTx) > 5 || Math.abs(endTy - startTy) > 5)) {
clearTimeout(lTapTimer);
lTapTimer = null;
}
}, false); this.addEventListener('touchend', function (e) {
if (lTapTimer) {
clearTimeout(lTapTimer);
lTapTimer = null;
}
}, false); } let box = document.querySelector('.box')
box.longTap(function() {
// your code ...
console.log('longTap 触发了')
})
swipe事件
HTMLElement.prototype.swipe = HTMLElement.prototype.swipe || function (callBack) {
let isTouchMove, startTx, startTy;
this.addEventListener('touchstart', function (e) {
let touches = e.touches[0];
startTx = touches.clientX;
startTy = touches.clientY;
isTouchMove = false;
}, false);
this.addEventListener('touchmove', function (e) {
isTouchMove = true;
e.preventDefault();
}, false);
this.addEventListener('touchend', function (e) {
if (!isTouchMove) {
return;
}
let touches = e.changedTouches[0],
endTx = touches.clientX,
endTy = touches.clientY,
distanceX = startTx - endTx
distanceY = startTy - endTy,
isSwipe = false;
if (Math.abs(distanceX) >= Math.abs(distanceY)) {
if (distanceX > 20) {
callBack('left')
console.log('fire swipe left event');
isSwipe = true;
} else if (distanceX < -20) {
callBack('right')
console.log('fire swipe right event');
isSwipe = true;
}
} else {
if (distanceY > 20) {
callBack('up')
console.log('fire swipe up event');
isSwipe = true;
} else if (distanceY < -20) {
callBack('down')
console.log('fire swipe down event');
isSwipe = true;
}
}
if (isSwipe) {
console.log('fire swipe event');
}
}, false);
}
let box = document.querySelector('.box')
box.swipe(function (direct) {
// your code ...
console.log('swipe 触发了' + direct)
})
移动端 之 触摸事件、Tap事件和swipe事件的更多相关文章
- 移动端click延迟和tap事件
一.click等事件在移动端的延迟 click事件在移动端和pc端均可以触发,但是在移动端有延迟现象. 1.背景 由于早期移动设备浏览网页时内容较小,为了增强用户体验,苹果公司专门为移动设备设计了双击 ...
- 移动端tap或touch类型事件的点透问题认识
1.什么是点透? 举例说明:下图B元素是黄色方块,B元素中包含了C元素,C元素是一个a链接,本身自带click事件按,然后又一个半透明的粉色元素A遮盖在B元素上(看图中A元素是覆盖在B元素上的,不然B ...
- 移动端-js触摸事件
开发者工具 在移动开发中,一种较为容易的做法是,先在桌面上开始原型设计,然后再在打算要支持的设备上处理移动特有的部分.多点触摸正是难以在PC上进行测试的那些功能之一,因为大部分的PC都没有触摸输入. ...
- 移动端touch触摸事件(滑动效果和手势操作)
一.定义 ①touch是移动端的触摸事件,而且是一组事件,主要有以下事件: touchstart 事件:当手指触摸屏幕的时候触发 touchmove 事件:当手指在屏幕来回滑动的时候触发 touche ...
- 移动端js触摸事件大全
一.手机上的触摸事件 基本事件: touchstart //手指刚接触屏幕时触发 touchmove //手指在屏幕上移动时触发 touchend //手指从屏幕上移开时触发 下面这 ...
- 2014-08-28——移动端,触摸事件 touchstart、touchmove、touchend、touchcancel
1.Touch事件简介在移动终端上的web页面触屏时会产生ontouchstart.ontouchmove.ontouchend.ontouchcancel 事件,分别对应了触屏开始.拖拽及完成触屏事 ...
- iOS开发系列--触摸事件、手势识别、摇晃事件、耳机线控
-- iOS事件全面解析 概览 iPhone的成功很大一部分得益于它多点触摸的强大功能,乔布斯让人们认识到手机其实是可以不用按键和手写笔直接操作的,这不愧为一项伟大的设计.今天我们就针对iOS的触摸事 ...
- 移动端touch触屏滑动事件、滑动触屏事件监听!
一.触摸事件 ontouchstart.ontouchmove.ontouchend.ontouchcancel 目前移动端浏览器均支持这4个触摸事件,包括IE.由于触屏也支持MouseEvent,因 ...
- 转发:iOS开发系列--触摸事件、手势识别、摇晃事件、耳机线控
-- iOS事件全面解析 转载来自崔江涛(KenshinCui) 链接:http://www.cnblogs.com/kenshincui/p/3950646.html 概览 iPhone的成功很大一 ...
随机推荐
- Springboot---显示图片/字符串/map集合/list集合
1.字符串/图片/map集合 @GetMapping("/hello") public String test(Model model){ String message=" ...
- 042、Java中逻辑运算之短路或运算“||”
01.代码如下: package TIANPAN; /** * 此处为文档注释 * * @author 田攀 微信382477247 */ public class TestDemo { public ...
- mysql limit查询入门
- P1051复数乘法
P1051复数乘法 转跳点:
- <老古董>线性支持向量机中的硬间隔(hard margin)和软间隔(soft margin)是什么
_________________________________________________________________________________________________ Th ...
- 3分钟教你用python制作一个简单词云
首先需要安装三个包: # 安装:pip install matplotlib # 安装:pip install jieba # 安装pip install wordcloud 1.制作英文字母的词云 ...
- 八十四、SAP中的ALV创建之三,创建ALV表格
一.销售表是2个表,一个抬头表,一个是销售内容表,数据库查询语句如下, 二.我们添加相关LAYOUT的格式控制如下 三.需要报每个字段都用相应的LAYOUT控制一下 四.点击模式,在模式里面,添加RE ...
- 备份CSDN
说明:https://blog.csdn.net/Feynman1999/article/details/87908082 源码:https://github.com/Feynman1999/CSDN ...
- 吴裕雄 Bootstrap 前端框架开发——Bootstrap 字体图标(Glyphicons):glyphicon glyphicon-indent-right
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name ...
- kafka 相关命令 偏移重置
kafka官方文档 https://kafka.apache.org/documentation.html#quickstart kafka 安装文档 https://www.jianshu.com/ ...