文章目录
- 1. 为什么鼠标单击的时候触发了`mousemove`事件?明明鼠标没有移动
- 2. 鼠标拖拽元素怎么能不触发单击事件?怎么处理鼠标在元素内的相对定位,而不是每次定位到左上角?
- 方式一:拖拽的元素没有注册click监听就不会触发单击事件绑定的函数
- 方式二:通过鼠标是否发生移动判断当前元素是需要移动还是需要单击
- 方式三:考虑鼠标在元素内相对定位问题,鼠标点击位置就是拖拽位置
- 3. 鼠标拖拽元素怎么能不触发选中文本?
- 方式一:鼠标按下时,阻止默认事件`e.preventDefault()`,不触发选中文本
- 方式二:鼠标按下时,修改当前元素style样式,鼠标抬起再取消
- 参考链接
鼠标拖拽需要注意什么问题?
鼠标拖拽会依次触发mousedown
mousemove
mouseup
click
事件。很多时候在一个元素既需要拖拽,又需要单击的时候,应该怎么避免在拖拽时不触发单击事件?不触发文本选中问题?
1. 为什么鼠标单击的时候触发了mousemove
事件?明明鼠标没有移动
?
2. 鼠标拖拽元素怎么能不触发单击事件?怎么处理鼠标在元素内的相对定位,而不是每次定位到左上角?
方式一:拖拽的元素没有注册click监听就不会触发单击事件绑定的函数
- 示例代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>测试拖拽</title>
<style>
body{
background-color: #f5f5f5;
}
#triggerDiv {
position: fixed;
left: 0px;
top: 0px;
width: 100px;
height: 100px;
background-color: red;
position: absolute;
text-align: center;
line-height: 100px;
vertical-align: middle;
cursor: pointer;
border-radius: 50%;
}
</style>
</head>
<body>
<div id="triggerDiv">
拖拽
</div>
</body>
<script>
let triggerELe = document.getElementById('triggerDiv')
let isMouseDown = false
// 鼠标按下
triggerELe.addEventListener('mousedown', function(e) {
isMouseDown = true
console.log('mousedown:', isMouseDown)
})
// 鼠标移动
triggerELe.addEventListener('mousemove', function(e) {
console.log('mousemove:', isMouseDown)
if (isMouseDown) {
triggerELe.style.left = e.clientX + 'px'
triggerELe.style.top = e.clientY + 'px'
}
})
// 鼠标抬起
triggerELe.addEventListener('mouseup', function(e) {
isMouseDown = false
console.log('mouseup:', isMouseDown)
})
// 鼠标离开:事件顺序 mouseout > mouseleave
// triggerELe.addEventListener('mouseout', function(e) {
// isMouseDown = false
// console.log('mouseout:', isMouseDown)
// })
// triggerELe.addEventListener('mouseleave', function(e) {
// isMouseDown = false
// console.log('mouseleave:', isMouseDown)
// })
// 给元素绑定了单击事件
// triggerELe.addEventListener('click', function(e) {
// console.log('click')
// })
</script>
</html>
- 通过对比是否绑定单击事件,判断单击是否被触发
方式二:通过鼠标是否发生移动判断当前元素是需要移动还是需要单击
- 如果
mousemove
事件没有被触发,那mouseup
发生时当前元素应该执行单击事件- 示例代码
<script>
let triggerELe = document.getElementById('triggerDiv')
let isMouseDown = false // 鼠标是否按下
let isMouseMove = false // 鼠标是否发生移动
// 鼠标按下
triggerELe.addEventListener('mousedown', function(e) {
console.log('mousedown')
isMouseDown = true
isMouseMove = false
})
// 鼠标移动
triggerELe.addEventListener('mousemove', function(e) {
console.log('mousemove')
isMouseMove = true
if (isMouseDown) {
triggerELe.style.left = e.clientX + 'px'
triggerELe.style.top = e.clientY + 'px'
}
})
// 鼠标抬起
triggerELe.addEventListener('mouseup', function(e) {
console.log('mouseup')
isMouseDown = false
if (isMouseMove) {
console.log('鼠标移动了')
} else {
console.log('鼠标没有移动,执行单击事件')
}
})
</script>
- 通过判断是否触发
mousemove
事件,决定是否执行单击事件
- 如果
mousedown
和mouseup
事件发生后,鼠标位置没有改变应该执行单击事件- 示例代码
<script>
let triggerELe = document.getElementById('triggerDiv')
let isMouseDown = false // 鼠标是否按下
// ========= 鼠标移动相关变量 ===========
let beforeX = 0 // 鼠标按下时的x坐标
let beforeY = 0 // 鼠标按下时的y坐标
let afterX = 0 // 鼠标抬起时的x坐标
let afterY = 0 // 鼠标抬起时的y坐标
// 鼠标按下
triggerELe.addEventListener('mousedown', function(e) {
console.log('mousedown')
isMouseDown = true
beforeX = e.offsetX
beforeY = e.offsetY
})
// 鼠标移动
triggerELe.addEventListener('mousemove', function(e) {
console.log('mousemove')
if (isMouseDown) {
triggerELe.style.left = e.clientX + 'px'
triggerELe.style.top = e.clientY + 'px'
}
})
// 鼠标抬起
triggerELe.addEventListener('mouseup', function(e) {
console.log('mouseup')
isMouseDown = false
afterX = e.offsetX
afterY = e.offsetY
console.log('beforeX:', beforeX, 'beforeY:', beforeY, 'afterX:', afterX, 'afterY:', afterY)
// 前后坐标相等,说明没有移动,执行单击事件
if (beforeX !== afterX || beforeY !== afterY) {
console.log('鼠标移动了')
} else {
console.log('鼠标没有移动,执行单击事件')
}
})
// // 给元素绑定了单击事件
// triggerELe.addEventListener('click', function(e) {
// console.log('click')
// })
</script>
- 思路:如果鼠标前后坐标没有发生变化执行单击事件
注!由于页面缩放问题,可能会出现鼠标没有移动但是前后坐标不一致的问题。
方式三:考虑鼠标在元素内相对定位问题,鼠标点击位置就是拖拽位置
<script>
let triggerELe = document.getElementById('triggerDiv')
let isMouseDown = false // 鼠标是否按下
// ========= 鼠标移动相关变量 ===========
let beforeX = 0 // 鼠标按下时的x坐标
let beforeY = 0 // 鼠标按下时的y坐标
let afterX = 0 // 鼠标抬起时的x坐标
let afterY = 0 // 鼠标抬起时的y坐标
let initX = 0 // 鼠标按下时的x坐标
let initY = 0 // 鼠标按下时的y坐标
// 鼠标按下
triggerELe.addEventListener('mousedown', function(e) {
console.log('mousedown')
isMouseDown = true
beforeX = e.offsetX
beforeY = e.offsetY
// 鼠标按下时的坐标
initX = e.offsetX
initY = e.offsetY
})
// 鼠标移动
triggerELe.addEventListener('mousemove', function(e) {
console.log('mousemove')
if (isMouseDown) {
triggerELe.style.left = (e.clientX - initX) + 'px'
triggerELe.style.top = (e.clientY - initY) + 'px'
// 鼠标移动时的坐标
afterX = e.offsetX + 'px'
afterY = e.clientY + 'px'
}
})
// 鼠标抬起
triggerELe.addEventListener('mouseup', function(e) {
console.log('mouseup')
isMouseDown = false
afterX = e.offsetX
afterY = e.offsetY
console.log('beforeX:', beforeX, 'beforeY:', beforeY, 'afterX:', afterX, 'afterY:', afterY)
// 前后坐标相等,说明没有移动,执行单击事件
if (beforeX !== afterX || beforeY !== afterY) {
console.log('鼠标移动了')
} else {
console.log('鼠标没有移动,执行单击事件')
}
})
// // 给元素绑定了单击事件
// triggerELe.addEventListener('click', function(e) {
// console.log('click')
// })
</script>
3. 鼠标拖拽元素怎么能不触发选中文本?
方式一:鼠标按下时,阻止默认事件e.preventDefault()
,不触发选中文本
<script>
let triggerELe = document.getElementById('triggerDiv')
let isMouseDown = false // 鼠标是否按下
// ========= 鼠标移动相关变量 ===========
let beforeX = 0 // 鼠标按下时的x坐标
let beforeY = 0 // 鼠标按下时的y坐标
let afterX = 0 // 鼠标抬起时的x坐标
let afterY = 0 // 鼠标抬起时的y坐标
let initX = 0 // 鼠标按下时的x坐标
let initY = 0 // 鼠标按下时的y坐标
// 鼠标按下
triggerELe.addEventListener('mousedown', function(e) {
console.log('mousedown')
isMouseDown = true
beforeX = e.offsetX
beforeY = e.offsetY
// 鼠标按下时的坐标
initX = e.offsetX
initY = e.offsetY
// 阻止默认事件
e.preventDefault()
})
// 鼠标移动
triggerELe.addEventListener('mousemove', function(e) {
console.log('mousemove')
if (isMouseDown) {
triggerELe.style.left = (e.clientX - initX) + 'px'
triggerELe.style.top = (e.clientY - initY) + 'px'
// 鼠标移动时的坐标
afterX = e.offsetX + 'px'
afterY = e.clientY + 'px'
}
})
// 鼠标抬起
triggerELe.addEventListener('mouseup', function(e) {
console.log('mouseup')
isMouseDown = false
afterX = e.offsetX
afterY = e.offsetY
console.log('beforeX:', beforeX, 'beforeY:', beforeY, 'afterX:', afterX, 'afterY:', afterY)
// 前后坐标相等,说明没有移动,执行单击事件
if (beforeX !== afterX || beforeY !== afterY) {
console.log('鼠标移动了')
} else {
console.log('鼠标没有移动,执行单击事件')
}
})
// // 给元素绑定了单击事件
// triggerELe.addEventListener('click', function(e) {
// console.log('click')
// })
</script>
方式二:鼠标按下时,修改当前元素style样式,鼠标抬起再取消
<script>
let triggerELe = document.getElementById('triggerDiv')
let isMouseDown = false // 鼠标是否按下
// ========= 鼠标移动相关变量 ===========
let beforeX = 0 // 鼠标按下时的x坐标
let beforeY = 0 // 鼠标按下时的y坐标
let afterX = 0 // 鼠标抬起时的x坐标
let afterY = 0 // 鼠标抬起时的y坐标
let initX = 0 // 鼠标按下时的x坐标
let initY = 0 // 鼠标按下时的y坐标
// 鼠标按下
triggerELe.addEventListener('mousedown', function(e) {
console.log('mousedown')
isMouseDown = true
beforeX = e.offsetX
beforeY = e.offsetY
// 鼠标按下时的坐标
initX = e.offsetX
initY = e.offsetY
// 不选中文字
triggerELe.style.userSelect = 'none'
// 添加css
// css
// .no-select {
// user-select: none
// }
})
// 鼠标移动
triggerELe.addEventListener('mousemove', function(e) {
console.log('mousemove')
if (isMouseDown) {
triggerELe.style.left = (e.clientX - initX) + 'px'
triggerELe.style.top = (e.clientY - initY) + 'px'
// 鼠标移动时的坐标
afterX = e.offsetX + 'px'
afterY = e.clientY + 'px'
}
})
// 鼠标抬起
triggerELe.addEventListener('mouseup', function(e) {
console.log('mouseup')
isMouseDown = false
afterX = e.offsetX
afterY = e.offsetY
console.log('beforeX:', beforeX, 'beforeY:', beforeY, 'afterX:', afterX, 'afterY:', afterY)
// 前后坐标相等,说明没有移动,执行单击事件
if (beforeX !== afterX || beforeY !== afterY) {
console.log('鼠标移动了')
// 移除css
// .no-select {
// user-select: text
// }
triggerELe.style.userSelect = 'text'
} else {
console.log('鼠标没有移动,执行单击事件')
}
})
// // 给元素绑定了单击事件
// triggerELe.addEventListener('click', function(e) {
// console.log('click')
// })
</script>
参考链接
可拖动DIV层的实现方法_可拖动的div-CSDN博客
Javascript设置拖拽时不触发点击事件_鼠标拖动列表,会触发列表项的点击事件,如何阻止-CSDN博客