1,移动端触摸事件
移动端触摸事件包括四种事件:开始触摸事件(touchstart)、结束触摸事件(touchend)、触摸移动事件(touchmove)、被动取消触摸事件(touchcancel)
- 被动取消触摸事件(触摸式来电、弹窗),火狐PC端浏览器模拟器无效
div.ontouchstart = e => console.log("touchstart");
div.ontouchend = e => console.log("touchend");
div.ontouchmove = e => console.log("touchmove");
div.ontouchcancel = e => console.log("touchcancel");
1.1 兼容指针事件
兼容指针事件:兼容各设备的指针事件(鼠标、触控笔和单点或多点的手机触摸)的指针事件
div.onpointerdown = e => console.log("pointerdown");
div.onpointerup = e => console.log("pointerup");
div.onpointermove = e => console.log("pointermove");
对比PC端鼠标事件、移动端触摸事件、兼容指针事件的区别:
- PC端鼠标事件和指针事件既可以在PC端触发,也可以在移动端触发,移动端触摸事件只能在移动端触发,在PC端无法触发
- 移动端触摸事件只有4种事件类型,而鼠标事件和指针事件事件类型更多
- 在移动端网页上,触摸事件和指针事件会立即触发,而鼠标事件不会立即触发,会有延迟(延迟事件为300ms)
如果想实现双击或者单击,长按,滑动我们可以自己封装一个双击事件,但是自己封装实现比较麻烦,可以使用插件hammer实现
1.2 hammer移动端手势插件
hammer插件封装了5各移动端手势事件,包括tap单击事件、doubletap双击事件、press长按事件、swipe滑动事件、pan移动事件
使用hammer之前需要引入hammer.js插件,使用插件提供的构造函数,新建一个对象,参数是绑定事件的标签。使用这个对象调用on函数给标签绑定事件
<script src="./hammer.min.js"></script>
<script>
// 使用插件提供的构造函数,新建一个对象,参数是绑定事件的标签
var hammer = new Hammer(document.body);
// 使用这个对象调用on函数给标签绑定事件
hammer.on("tap", () => {
console.log("单击");
})
hammer.on("doubletap", () => {
console.log("双击");
})
hammer.on("press", () => {
console.log("长按");
})
hammer.on("swipe", e => {
console.log("滑动", e.direction, e.angle);
})
hammer.on("pan", () => {
console.log("移动");
})
// 总结,hammer插件封装了5个移动端手势事件,tap单击,doubletap双击,press长按,swipe滑动,pan移动
</script>
2,移动端手势穿透
2.1 手势穿透概念
<input id="input" type="text">
<div id="cover"></div>
<script>
var input = document.getElementById("input")
var cover = document.getElementById("cover")
input.ontouchstart = function() {
console.log("input-touchstart")
}
input.onmousedown = function() {
console.log("input-mousedown")
}
input.onclick = function() {
console.log("input-click")
}
cover.ontouchstart = function() {
cover.remove()
}
</script>
以上代码出现一种现象:点击上层cover时,cover移除了,但莫名的触发了下层input输入框的mousedown事件,这种现象叫做手势穿透
原因:click/mousedown事件出发后有300ms的延迟响应,当点击遮罩层时,touchstart事件触发即立即响应,执行隐藏,而click/nousedown事件触发会在0.3s之后响应,而在0.3s之后,遮罩层已经隐藏,则由下层输入框响应这个click/mousedown事件,而获取焦点
2.2 避免手势穿透的三种方法
- 阻止cover上层视图的touched事件的默认行为
- 延迟300ms执行遮罩层cover的隐藏,click响应时,cover还在,即响应给cover
- 使用插件fastcick.js防止手势穿透,这个插件专为解决手势穿透现象而生。
2.2.1 阻止cover上层视图的touched事件的默认行为
cover.ontouchend = function(e) {
e.preventDefault()
}
2.2.2 延迟300ms执行遮罩层cover的隐藏,click响应时,cover还在,即响应给cover
cover.ontouchstart = function() {
setTimeout(() => {
cover.remove()
}, 300);
}
2.2.3 使用fastclick插件防止手势穿透,这个插件专为解决手势穿透现象而生
fastclick取消click事件300ms延迟的原理:fastclick监听了click事件的触发,当body上触发了click事件时,fastclick会自定义一个事件,并立即触发,并把监听到的系统click事件阻止掉
FastClick.attach(cover)