Touch事件
只能在移动端触发
Touch事件的event对象
event对象的常用属性
- type 事件类型
- target目标元素
- touches 屏幕上的所有触摸点
- targetTouches 目标上所有触摸点
- changedTouches 事件触发时,状态发生了改变的所有触摸点
触摸点的常用属性
触摸点:const touch=evt.changedTouches[0]
- identifier 触摸点id(唯一标识符),一般多指触摸有用
- target 目标元素
- screenX/screenY 触点相对于屏幕左边缘的X、Y坐标
- clientX/clientY 触点相对于可视区域左边缘的X、Y坐标。不包括任何滚动偏移
- pageX/pageY 触点相对于 HTML 文档左边缘的X、Y坐标。包括滚动偏移
阻止浏览器的默认行为
- 可以在 touch 的事件处理函数中使用 evt.preventDefault() 阻止浏览器的默认行为
- touch-action 告诉浏览器哪些触摸操作让浏览器处理,阻止其他触摸操作的默认行为(css样式)
- touch-action: pan-y允许垂直平移/ manipulation只允许进行滚动和持续缩放操作,不允许双击缩放
单指拖拽
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>单指拖拽</title>
<style>
.box{
width: 200px;
height: 200px;
background-color: red;
}
</style>
</head>
<body style="height: 2000px;">
<div class="box" id="box"></div>
<script>
const drag=$el=>{
// 每次拖拽最开始的触摸点
const startPoint={};
// 拖拽过程中移动到的点
const movePoint={};
// 被拖拽元素的当前位置
const curPos={
x:0,
y:0
};
$el.addEventListener('touchstart',startHandler,false);
$el.addEventListener('touchmove',moveHandler,false);
$el.addEventListener('touchend',endHandler,false);
$el.addEventListener('touchcancel',cancelHandler,false);
function startHandler(evt){
const touch=evt.changedTouches[0];
startPoint.x=touch.pageX;
startPoint.y=touch.pageY;
}
function endHandler(){
curPos.x=movePoint.x;
curPos.y=movePoint.y;
}
function moveHandler(evt){
evt.preventDefault();
const touch=evt.changedTouches[0];
movePoint.x=curPos.x+touch.pageX-startPoint.x;
movePoint.y=curPos.y+touch.pageY-startPoint.y;
$el.style.transform=`translate3d(${movePoint.x}px,${movePoint.y}px,0)`;
}
};
drag(document.getElementById('box'));
</script>
</body>
</html>
Pointer事件
pc端类似于mouse事件移动端类似于touch事件
触摸点移出目标元素,touchmove事件依然会持续触发,pointermove和mousemove事件不会再触发
Pointer事件的event对象
event对象的常用属性
- pointerId 指针id(唯一标识符)
- type 事件类型
- pointerType 指针类型(鼠标/笔/触摸等)
- target 目标元素
- screenX/screenY 指针相对于屏幕左边缘的X、Y坐标
- clientX/clientY 指针相对于可视区域左边缘的X、Y坐标。不包括任何滚动偏移
- pageX/pageY 指针相对于 HTML 文档左边缘的X、Y坐标。包括滚动偏移
阻止浏览器的默认行为
- Pointer 的事件处理函数中,evt.preventDefault() 阻止的是 PC 端的默认行为(不能阻止 scrolling, pinch/zoom, 鼠标事件等默认行为,可以阻止图片拖动的默认行为)
- 可以在 touch 的事件处理函数中使用 evt.preventDefault() 阻止移动端的默认行为
- touch-action 设置触摸操作时浏览器的默认行为
单指拖拽
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>单指拖拽</title>
<style>
.box {
width: 200px;
height: 200px;
background-color: red;
}
</style>
</head>
<body>
<div id="box" class="box"></div>
<script>
// 1.touch 拖拽
// const drag = $el => {
// // 每次拖拽最开始的触摸点
// const startPoint = {};
// // 拖拽过程中移动到的点
// const movePoint = {};
// // 被拖拽元素的当前位置
// const curPos = {
// x: 0,
// y: 0
// };
// $el.addEventListener('touchstart', startHandler, false);
// $el.addEventListener('touchmove', moveHandler, false);
// $el.addEventListener('touchend', endHandler, false);
// $el.addEventListener('touchcancel', endHandler, false);
// function startHandler(evt) {
// const touch = evt.changedTouches[0];
// startPoint.x = touch.pageX;
// startPoint.y = touch.pageY;
// }
// function moveHandler(evt) {
// evt.preventDefault();
// const touch = evt.changedTouches[0];
// movePoint.x = curPos.x + touch.pageX - startPoint.x;
// movePoint.y = curPos.y + touch.pageY - startPoint.y;
// $el.style.transform = `translate3d(${movePoint.x}px, ${movePoint.y}px, 0)`;
// }
// function endHandler() {
// curPos.x = movePoint.x;
// curPos.y = movePoint.y;
// }
// };
// 2.仿照 touch 的 Pointer 拖拽(有问题)
// const drag = $el => {
// // 每次拖拽最开始的触摸点
// const startPoint = {};
// // 拖拽过程中移动到的点
// const movePoint = {};
// // 被拖拽元素的当前位置
// const curPos = {
// x: 0,
// y: 0
// };
// $el.addEventListener('pointerdown', startHandler, false);
// $el.addEventListener('pointermove', moveHandler, false);
// $el.addEventListener('pointerup', endHandler, false);
// $el.addEventListener('pointercancel', endHandler, false);
// $el.addEventListener(
// 'touchstart',
// evt => {
// evt.preventDefault();
// },
// false
// );
// function startHandler(evt) {
// startPoint.x = evt.pageX;
// startPoint.y = evt.pageY;
// }
// function moveHandler(evt) {
// evt.preventDefault();
// movePoint.x = curPos.x + evt.pageX - startPoint.x;
// movePoint.y = curPos.y + evt.pageY - startPoint.y;
// $el.style.transform = `translate3d(${movePoint.x}px, ${movePoint.y}px, 0)`;
// }
// function endHandler() {
// curPos.x = movePoint.x;
// curPos.y = movePoint.y;
// }
// };
// 3.使用技巧后的 Pointer 拖拽
const drag = $el => {
// 每次拖拽最开始的触摸点
const startPoint = {};
// 拖拽过程中移动到的点
const movePoint = {};
// 被拖拽元素的当前位置
const curPos = {
x: 0,
y: 0
};
$el.addEventListener('pointerdown', startHandler, false);
// $el.addEventListener('pointermove', moveHandler, false);
// $el.addEventListener('pointerup', endHandler, false);
// $el.addEventListener('pointercancel', endHandler, false);
$el.addEventListener(
'touchstart',
evt => {
evt.preventDefault();
},
false
);
function startHandler(evt) {
startPoint.x = evt.pageX;
startPoint.y = evt.pageY;
document.addEventListener('pointermove', moveHandler, false);
document.addEventListener('pointerup', endHandler, false);
document.addEventListener('pointercancel', endHandler, false);
}
function moveHandler(evt) {
evt.preventDefault();
movePoint.x = curPos.x + evt.pageX - startPoint.x;
movePoint.y = curPos.y + evt.pageY - startPoint.y;
$el.style.transform = `translate3d(${movePoint.x}px, ${movePoint.y}px, 0)`;
}
function endHandler() {
curPos.x = movePoint.x;
curPos.y = movePoint.y;
document.removeEventListener('pointermove', moveHandler, false);
document.removeEventListener('pointerup', endHandler, false);
document.removeEventListener('pointercancel', endHandler, false);
}
};
drag(document.getElementById('box'));
</script>
</body>
</html>
手势模拟
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>手势模拟</title>
<style>
img{
width: 100%;
}
.box{
margin: 100px auto;
width: 200px;
height: 200px;
background-color: red;
}
</style>
</head>
<body>
<!-- <img src="./gesture.png" alt="移动端手势"> -->
<div id="box" class="box"></div>
<script>
// 1.滑动手势
function swipe($el,cb){
// 最开始的触摸点
const start={};
const threhold={
time:500,//上限
distance:100 //下限
};
$el.addEventListener('pointerdown',startHandler,false);
// 阻止移动端的默认行为
$el.addEventListener('touchstart',evt=>{
evt.preventDefault();
},false);
function startHandler(evt){
// 阻止PC端的默认行为
evt.preventDefault();
start.time=new Date().getTime();//按下去时间
start.x=evt.pageX;//坐标
start.y=evt.pageY;//坐标
document.addEventListener('pointerup',endHandler,false);
document.addEventListener('pointercancel',endHandler,false);
}
function endHandler(evt){
const delta={};
let direction='';
delta.time=new Date().getTime()-start.time;
delta.x=evt.pageX-start.x;
delta.y=evt.pageY-start.y;
if(delta.time>threhold.time||(Math.abs(delta.x)<threhold.distance&&Math.abs(delta.y)<threhold.distance)){
// 扫太慢或扫的距离太短,不是扫动手势
return;
}else{
// 判断扫动方向
if(Math.abs(delta.x)>=Math.abs(delta.y)){
// 左右扫动
if(delta.x>0){
// 右扫
direction='right';
}else{
// 左扫
direction='left';
}
}else{
// 上下扫动
if(delta.y>0){
// 下扫
direction='down';
}else{
// 上扫
direction='up';
}
}
cb.call($el,direction);
}
document.removeEventListener('pointerup',endHandler,false);
document.removeEventListener('pointercancel',endHandler,false);
}
}
swipe(document.getElementById('box'),function(direction){
//console.log(this);
console.log(direction);
})
</script>
</body>
</html>