难点:移动端与pc端的事件属性不一样,需要计算好偏移量才能跟着移动。
一、原理
首先需要获取到点击的位置距离元素el距离(top,left)
在添加移动事件:通过每次获得移动获得到在页面的具体位置(x,y)
元素el所距离page边框的距离为:
左边距离 = x - left;
上边距离 = y - left;
二、具体实现
<!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>Document</title>
</head>
<body>
<div id="block"></div>
</body>
<style>
#block {
width: 100px;
height: 100px;
background-color: orangered;
position: fixed;
}
</style>
<script>
var el = document.querySelector("#block")
var t1;
var Top = 0;
var Left = 0;
function moveEl(e) {
//判断是否有延迟函数
if (t1 != -1) {
clearTimeout(t1);
t1 = -1;
}
let clientY = e.clientY ?? e.touches[0].clientY;
let clientX = e.clientX ?? e.touches[0].clientX;
el.style.top = clientY - Top + "px";
el.style.left = clientX - Left + "px";
console.log(Top);
}
//鼠标点击和触屏点击
function mouseDown(e) {
// 移动端无法直接获取与父元素的位置信息,
// 所以需要减去父元素与页面的位置:parseInt(win.value.style.top)
Top = e.offsetY ?? e.touches[0].pageY - parseInt(el.style.top || 0);
Left = e.offsetX ?? e.touches[0].pageX - parseInt(el.style.left || 0);
//取消拖动时会选中文字,不取消会出现事件无法取消bug
document.body.onselectstart = document.body.ondrag = function () {
return false;
};
// 添加事件
window.addEventListener("mousemove", moveEl);
// 适配触摸屏
window.addEventListener("touchmove", moveEl);
}
// 鼠标右键松开事件
function mouseUp(e) {
//取消拖动时不会选中文字
document.body.onselectstart = document.body.ondrag = function () {
return true;
};
// 移出事件
window.removeEventListener("mousemove", moveEl);
//适配触摸
window.removeEventListener("touchmove", moveEl);
}
// 鼠标移出事件
function mouseOut() {
//解决频繁移出bug
if (t1 != -1) return;
//由于浏览器刷新有延迟需防抖移出
t1 = setTimeout(() => {
window.removeEventListener("mousemove", moveEl);
}, 800);
}
el.addEventListener("mousedown", mouseDown)
el.addEventListener("mouseup", mouseUp)
el.addEventListener("mouseout", mouseOut)
// 移动端事件
el.addEventListener("touchstart", mouseDown)
el.addEventListener("touchend", mouseUp)
</script>
</html>