typora-root-url: assetis
第五章:移动端事件
目标
会使用移动端事件开发移动端特效
移动端事件封装
会使用touch.js移动端事件库
1、移动端事件
我们之前学习的电脑端事件,点击,双击,鼠标事件等,在手机端是没有的,因为我们很少见到有人在手机上用一个鼠标进行操作,取而代之的是触摸事件等
- 点击事件
- 双击事件
- 滑动事件
- 上滑、下滑、左滑、右滑
- 长按事件
- 摇一摇、重力感应等
300ms延时
在移动端上使用click事件
var span = document.getElementsByTagName('span')[0];
span.onclick = function () {
alert('点击了span元素');
};
300ms产生的原因
1、移动浏览器上支持的 双击缩放操作,以及 IOS系统 上的双击滚动操作,是导致300ms的点击延迟主要原因。 2、手指在屏幕上快速点击两次,移动端浏览器会将网页缩放至原始比例。 那么这和 300 毫秒延迟有什么联系呢? 假定这么一个场景。用户在 浏览器里边点击了一个链接。由于用户可以进行双击缩放或者双击滚动的操作,当用户点击 一次屏幕之后,浏览器并不能立刻判断用户是确实要打开这个链接,还是想要进行双击操作。因此,浏览器就等待 300 毫秒,以判断用户是否再次点击了屏幕 ,如果 300ms之内再次点击 就会认为是 双击操作,如果300ms 内 没有再次去点击,就认为是单击。 3、在移动WEB兴起的初期,用户对300ms的延迟感觉不明显。但是,随着用户对交互体验的要求越来越高,现今,移动端300ms的点击延迟逐渐变得明显,那我们该如何解决这个问题呢? 两种方式,
第一种 :使用移动端专门提供的事件
第二种,可以使用插件解决 300ms延时问题 后面课程会讲解到这两种方式;
2、Touch事件模型
touchstart | 手指刚接触屏幕时触发 |
touchmove | 手指在屏幕上移动时触发 |
touchend | 手指从屏幕上移开时触发 |
touchcancel | 当一些更高级别的事件发生的时候(如电话接入或者弹出信息)会取消当前的touch操作,即触发touchcancel。一般会在touchcancel时暂停游戏、存档、暂停视频音乐等操作 |
注意,在绑定事件的时候,要加上关键字on
如:
div.ontouchmove = function(){
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>移动端事件</title>
<style>
div {
width: 300px;
height: 500px;
background-color: skyblue;
}
</style>
</head>
<body>
<div></div>
</body>
<script>
var div_ = document.getElementsByTagName('div')[0];
// 手指触摸的时候背景颜色变红色
div_.ontouchstart = function () {
div_.style.backgroundColor = 'red';
}
// 手指在屏幕移动的时候
div_.ontouchmove = function () {
div_.style.backgroundColor = 'yellow';
}
// 手指离开屏幕的时候
div_.ontouchend = function () {
div_.style.backgroundColor = 'green';
}
// 触发高级事件的时候
div_.ontouchcancel = function () {
div_.style.backgroundColor = 'pink';
}
</script>
</html>
触摸属性(event)
touches:表示当前跟踪的触摸操作的touch对象的数组(当前位于屏幕上的所有手指触摸点的一个列表)
- 当一个手指在触屏上时, event.touches.length=1
- 当两个手指在触屏上时, event.touches.length=2,以此类推
changedTouches:触发事件时改变的触摸点的集合
哪根手指点击的事件,保存哪根手指触摸点的数据
targetTouches:绑定事件的那个结点上的触摸点的集合列表(谁点了点击事件 保存谁)
总结:
- touches: 当前屏幕上所有触摸点的集合列表(保存屏幕上所有的触点)
- targetTouches: 绑定事件的那个结点上的触摸点的集合列表(谁点了点击事件 保存谁)
- changedTouches: 触发事件时改变的触摸点的集合()
举例来说,比如div1, div2只有div2绑定了touchstart事件,第一次放下一个手指在div2上,触发了touchstart事件,这个时候,三个集合的内容是一样的,都包含这个手指的touch,然后,再放下两个手指一个在div1上,一个在div2上,这个时候又会触发事件,但changedTouches里面只包含第二个第三个手指的信息,因为第一个没有发生变化,而targetTouches包含的是在第一个手指和第三个在div2上的手指集合,touches包含屏幕上所有手指的信息,也就是三个手指
触摸事件坐标(event事件对象中)
查看触摸event对象:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
div{
width: 100%;
height: 500px;
background-color: skyblue;
}
</style>
</head>
<body>
<div></div>
</body>
<script>
var div = document.getElementsByTagName('div')[0];
div.ontouchstart = function(e){
e = e||window.event;
console.log(e);
}
</script>
</html>
clientX | 触摸目标在视口中的x坐标 视觉视口 |
clientY | 触摸目标在视口中的y坐标 视觉视口 |
identifier | 标识触摸的唯一ID |
pageX | 触摸目标在页面中的x坐标 布局视口 |
pageY | 触摸目标在页面中的y坐标 布局视口 |
screenX | 触摸目标在屏幕中的x坐标 |
screenY | 触摸目标在屏幕中的y坐标 |
target | 触摸的DOM节点目标,返回触摸的元素 |
注意:
clientX/Y和pageX/Y的区别:
clientX/Y:相对于视觉视口的左上角
pageX/Y:相对布局视口的左上角。布局视口 是可以滚动的
<script>
var div = document.getElementsByTagName('div')[0];
div.ontouchstart = function(e){
e = e||window.event;
console.log(e);
str = '';
for(var i = 0;i<e.changedTouches.length;i++){
str += '第'+(i+1)+'根手指的id是:'+e.changedTouches[i].identifier;
str +='<br>第'+(i+1)+'根手指的screenx坐标:'+e.changedTouches[i].screenX;
str +='<br>第'+(i+1)+'根手指的screenY坐标:'+e.changedTouches[i].screenY;
div.innerHTML = str;
}
}
</script>
3、移动端事件封装
实操-单击事件
封装单击事件:
为什么要封装单击事件?
比如:
我们现在给同一个元素绑定了点击和移动两个事件
因为移动端的屏幕非常小,点击完以后,手在抬起来的时候,很容易造成一点的移动偏差
此时就很容易触发移动事件
我们需要进行一个判断,比如手在抬起来的时候,位置偏差范围多少的情况下视为单击离开
偏差多少的范围外,视为移动事件
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>封装单击事件</title>
<style>
*{
margin: 0;
padding: 0;
}
.div1,.div2{
height: 200px;
background-color: skyblue;
margin-bottom: 30px;
}
</style>
</head>
<body>
<div class="div1"></div>
<div class="div2"></div>
</body>
<script>
var div1 = document.getElementsByClassName('div1')[0];
var div2 = document.getElementsByClassName('div2')[0];
// 把点击事件封装成对象的方法
var touchEvent = {
tab:function(el){
var end_x,end_y,start_x,start_y;
el.ontouchstart = function(e){
e =e||window.event;
// 获取按下动作的x值和y值
start_x = e.changedTouches[0].clientX;
start_y = e.changedTouches[0].clientY;
}
el.ontouchend = function(e){
e = e||window.event;
//获取抬起动作的x值和y值
end_x = e.changedTouches[0].clientX;
end_y = e.changedTouches[0].clientY;
if(Math.abs(end_x-start_x)<10 && Math.abs(end_y-start_y)<10){
alert('您调用了点击事件')
}else{
alert('您调用了移动事件');
}
}
}
}
touchEvent.tab(div1);
touchEvent.tab(div2);
</script>
</html>
4、移动端事件库
Touch.js
Touch.js
是移动设备上的手势识别与事件库, 由百度云Clouda团队维护,也是在百度内部广泛使用的开发工具.(已停更)
Touch.js
手势库专为移动设备设计,是Web移动端touch点击事件不错的解决方案
https://github.com/Clouda-team/touchjs
支持移动端事件(部分)
属性 | 设备类型 |
tap | 单击屏幕 |
doubletap | 双击屏幕 |
swipe | 滑动 |
swipeleft | 向左滑动 |
swiperight | 向右滑动 |
swipeup | 向上滑动 |
swipedown | 向下滑动 |
hold | 长按屏幕 |
dragstart | 拖动开始 |
drag | 拖动 |
pinchstart | 缩放手势起点 |
pinchin | 收缩 |
pinchout | 放大 |
用法:
//引入touchjs
<script src="js/touch-0.2.14.min.js"></script>
/*
touch.on(1,2,3)
三个参数:
1、DOM元素
2、移动端事件
3、处理函数
*/
touch.on(oBox, 'tap', function(ev) {
this.style.background = "red";
this.style.color = '#fff';
});
示例:
<script>
var div = document.getElementsByTagName('div')[0];
touch.on(div,'tap',function(){
this.style.backgroundColor = 'red';
});
touch.on(div,'doubletap',function(){
this.style.backgroundColor = 'green';
});
// 长按
touch.on(div,'hold',function(){
alert('长按');
this.style.backgroundColor = 'yellow';
})
// 拖动
touch.on(div,'drag',function(){
this.style.backgroundColor = 'pink';
})
</script>
hammer.js
一款开源的移动端脚本框架,他能完美的实现在移端开发的大多数事件,如点击、滑动、拖动、多点触控等事件
http://hammerjs.github.io/getting-started/
用法:
<script src="js/hammer.min.js"></script>
//创建一个新的hammer对象并且在初始化时指定要处理的dom元素
var hammertime = new Hammer(document.getElementById("test"));
//添加事件
// tap、swipe、rotate、press、pinch、pan等事件,这里就给大家演示tap,剩余的大家可以课下自行学习
hammertime.on("tap", function(e) {
document.getElementById("result").innerHTML += "点击触发了,长按无效<br />";
//控制台输出,可以自行查看相关的参数
console.log(e);
});
点透现象
/* 点击第一层第一个,令其消失*/
b.addEventListener('touchstart', function(e) {
level10.style.display = 'none';
});
a.onclick = function() {
console.log('看下会不会被点击到');
}
点透发生的条件
A 和 B不是后代继承关系,而是兄弟关系
b发生touch, b touch后立即消失, a事件绑定click
b显示在a浮层之上
<style>
div{
width: 100%;
height: 200px;
}
.a{
position: absolute;
background-color: rgb(241, 71, 71);
}
.b{
position: absolute;
background-color: rgb(70, 145, 41);
}
</style>
</head>
<body>
<div class="a"></div>
<div class="b"></div>
</body>
<script>
var a = document.getElementsByClassName('a')[0];
var b = document.getElementsByClassName('b')[0];
b.addEventListener('touchstart',function(){
b.style.display = 'none';
});
a.onclick = function(){
alert('a显示出来了,红色的');
}
</script>
解决点透问题
将click换成移动端事件
// a.onclick = function(){
// alert('a显示出来了,红色的');
// }
a.ontouchstart = function(){
alert('a显示出来了,红色的');
}
不建议使用:
e.preventDefault()
// 阻止pc的事件
document.addEventListener('touchend', function(e){
// 可以阻止本次点击系统触发的click事件
e.preventDefault();
}, false);
标签:function,触摸,点击,第五章,事件,div,移动
From: https://blog.51cto.com/u_13937224/8042403