移动端 之 触摸事件、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的成功很大一 ...
随机推荐
- Ado.NET SQLHelper(2)
测试发现前面发的那个功能太简单,不能调用getdate()等内部函数. 完善后重载了insert和update两个功能,将函数作为字符串传入SQL语句构造,需要的可以试用一下 using Sys ...
- android studio (安卓开发)如何使用外部模拟器(mumu模拟器)调试运行程序
开发安卓 我觉得大家明白自带的模拟器卡的要死而且启动慢(我觉得八核的计算机应该可以解决这个问题),这里使androidstudio 使用外部模拟器 MuMu模拟器 配置方法 eclipse 开发安卓 ...
- UVA - 1513 Movie collection (树状数组)
题意:有n个影碟,标号为1~n,位置为0~n-1,每次取出一个影碟看完后,将其放在最前面(标号为0处),问每个影碟取出前,其位置之前有多少个影碟. 分析: 1.数组大小开为100000*2,后1000 ...
- CodeForces - 755B PolandBall and Game(博弈)
题意:A和B两人每人都熟悉一些单词.A先开始,每人说一个单词,单词不能与两人之前说过的所有单词重复,谁无话可说谁输.两人可能有共同会的单词. 分析:因为要让对方尽量无单词可说,所以每个人优先说的都是两 ...
- LocalDateTime整合到SpringBoot + MyBatis中
啥也不说先贴两个代码: 一:MVC层配置 @Configuration public class JacksonConfig { /** 默认日期时间格式 */ public static final ...
- Oracle SQL存储过程结构、异常处理示例
-- 存储过程结结构. -- EXCeption不是存储过程必须部分,可以用作本存储过程的异常处理,但如果没有异常处理,出了异常将会终止程序 CREATE PROCEDURE procedure_na ...
- PowerDesigner创建索引
防止以后忘记怎么设置索引,记录下来方便查翻 1:选中Table 2:找到Table对应的Indexes 3:选中一条记录,点击红框中的小手(Properties)或双击该记录,进入到详细里面 4:找到 ...
- Spring Cloud 支付宝支付的流程
沙箱环境又称沙盘,为了开发与调试所提供的环境,它与生产环境互相隔离,但具有生产环境几乎完全相同的功能蚂蚁金服开放平台——开发者中心1.https://openhome.alipay.com2.提供的调 ...
- vzray服务端配置
打开securecrt登陆服务器 输入命令:bash <(curl -s -L https://git.io/vzray.sh)1 回车tcp 回车端口 回车默认 回车
- Mysql:分支结构—case结构
case结构 情况一:类似于家擦中的switch语句 一般用于实现等值判断 语法: CASE 变量|表达式|字段 WHEN 要判断的值 THEN 返回的值1或语句1; WHEN 要判断的值 THEN ...