在 html 的应用中,拖拽事件为 mousedown -> mousemove -> mouseup 三个事件组成,在一个有拖拽事件的 div 中监听一个 click 事件,当拖拽之后也会出发 click 事件,为了不让拖拽事件影响到点击事件,需要区分点击事件和拖拽事件
PC 端
- 示例代码
<!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>Click</title>
<style>
#container {
width: 500px;
height: 500px;
background-color: aqua;
}
</style>
</head>
<body>
<div id="container"></div>
<script>
const container = document.getElementById('container');
container.addEventListener('mousedown', (event) => {
console.log('mousedown event is', event)
})
container.addEventListener('mouseup', (event) => {
console.log('mouseup event is', event)
})
</script>
</body>
</html>
当点击时,可以查看打印信息
- 点击时的打印信息
- 拖拽后的打印信息
可以看出点击后的 mousedown 和 mouseup 的 MouseEvent 的 clientX 与 clientY 的值是相等的,而拖拽后的 clientX 与 clientY 的值不同,故可以通过判断 clientX 和 clientY 的值来判断点击事件或者拖拽事件,修改后的代码为:
<!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>Click</title>
<style>
#container {
width: 500px;
height: 500px;
background-color: aqua;
}
</style>
</head>
<body>
<div id="container"></div>
<script>
const clientOffset = {};
const container = document.getElementById('container');
container.addEventListener('mousedown', (event) => {
clientOffset.clientX = event.clientX;
clientOffset.clientY = event.clientY;
})
container.addEventListener('mouseup', (event) => {
const clientX = event.clientX;
const clientY = event.clientY;
if (clientX === clientOffset.clientX && clientY === clientOffset.clientY) {
console.log('click');
} else {
console.log('drag');
}
})
</script>
</body>
</html>
移动端
在移动端中,点击以及拖拽时没有 mousedown 和 mouseup 事件,所以我们需要使用移动端的事件,移动端的事件如下
事件 | 作用 | 与 pc 端对应 |
---|---|---|
touchstart | 手指按倒屏幕上 | mousedown |
touchmove | 手指在屏幕上滑动 | mousemove |
touchend | 手指离开屏幕 | mouseup |
touchcancle | 特殊情况下关闭/退出时触发 | - |
所以我们需要使用 touchstart 和 touchend 来代替 mousedown 和 mouseup,并且 TouchEvent 接口的点击位置在 event.changeTouches 列表中记录,所以取 clientOffset 值的时候需要从 changeTouches 列表中取值
- 示例代码
<!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>Click</title>
<style>
#container {
width: 200px;
height: 200px;
background-color: aqua;
}
</style>
</head>
<body>
<div id="container"></div>
<script>
const clientOffset = {};
const container = document.getElementById('container');
container.addEventListener('touchstart', (event) => {
clientOffset.clientX = event.changedTouches[0].clientX;
clientOffset.clientY = event.changedTouches[0].clientY;
})
container.addEventListener('touchend', (event) => {
const clientX = event.changedTouches[0].clientX;
const clientY = event.changedTouches[0].clientY;
if (clientX === clientOffset.clientX && clientY === clientOffset.clientY) {
console.log('click');
} else {
console.log('drag');
}
})
</script>
</body>
</html>