经上一篇拖拽排序的启发,本篇手写一个拖拽定位。
在工作中经常会遇到需要在页面上写悬浮按钮,但是位置固定的话总会遮挡页面,所以本篇实现允许将悬浮按钮拖拽到指定位置,就像这样。
HTML&CSS
html和css部分很简单,就是在页面上画一个悬浮按钮
.drag {
position: fixed;
top: 20px;
left: 300px;
width: 50px;
object-fit: cover;
}
<body>
<img src="https://mainaer-img.oss-cn-hangzhou.aliyuncs.com/mainaer-EIM/logo.png" class="drag"></img>
</body>
按下鼠标或者触控板(mousedown)
mousedown事件在指针设备按钮按下时触发。
在鼠标按下时记录指针与悬浮按钮的边距的偏移量,left值就等于指针x轴坐标减去左边的偏移量,top值就等于指针y轴坐标减去顶部的偏移量,如图所示:
const drag = document.querySelector('.drag');
let dragging = false, offsetLeft = 0, offsetTop = 0;
drag.onmousedown = (e) => {
e.preventDefault();
const { left, top } = drag.getBoundingClientRect(); // 获取悬浮按钮当前的top值和left值
drag.classList.remove('transition-left'); // 移除过渡效果
offsetLeft = e.clientX - left; // 点击的x轴坐标距悬浮按钮左边的距离
offsetTop = e.clientY - top; // 点击的y轴坐标距悬浮按钮顶部的距离
dragging = true; // 拖动状态
};
开始拖动(mousemove)
当指针设备 ( 通常指鼠标 ) 在元素上移动时,
mousemove事件被触发。
在拖动时,实时计算left值和top值,且两个值的大小都在0-max这个区间内
document.onmousemove = (e) => {
e.preventDefault();
if(dragging) { // 只在拖动状态下处理
// 获取悬浮按钮的节点信息
const { left, top, width, height } = drag.getBoundingClientRect();
// 可拖动的最大值,即悬浮按钮在右下角时的top值和left值
const maxLeft = window.innerWidth - width, maxTop = window.innerHeight - height;
// 设置left值
if(left >= 0 && left <= maxLeft) drag.style.left = countPosition(e.clientX, offsetLeft, maxLeft) + 'px';
// 设置top值
if(top >= 0 && top <= maxTop) drag.style.top = countPosition(e.clientY, offsetTop, maxTop) + 'px';
}
};
// 计算当前的left值或者top值,在0 - max之间
function countPosition(clientSize, offsetSize, maxSize) {
const value = clientSize - offsetSize
if(value < 0) {
return 0;
} else if(value >= 0 && value <= maxSize) {
return value;
} else {
return maxSize;
}
};
松开鼠标或者触控板(mouseup)
当指针在元素中时,
mouseup事件在指针设备(如鼠标或触摸板)按钮放开时触发。mouseup事件与mousedown事件相反。
在结束拖动时,根据当前悬浮按钮的位置自动回退到窗口左边或者右边
document.onmouseup = (e) => {
e.preventDefault();
dragging = false; // 取消拖动态
drag.classList.add('transition-left'); // 添加过渡效果
const {left, width} = drag.getBoundingClientRect();
// 当此时的悬浮按钮在左半屏的时候,自动回退到左边
if((window.innerWidth - width) / 2 >= left) {
drag.style.left = '10px';
} else {
// 自动回退到右边
drag.style.left = window.innerWidth - width - 10 + 'px';
}
};
// 过渡效果
.transition-left {
transition: left .5s;
}
至此,拖动定位的效果就实现了。
前端小渣渣的学习总结,如有错误,欢迎指正!!