let father = document.querySelector('.father');
有时页面内容过多时,会同时出现水平和垂直滚动条。用鼠标拖动滚动条感觉有点麻烦,所以尝试直接拖动dom来达到与拖动滚动条相同的效果
<style>
.father {
height: 50vh;
width: 70vw;
overflow: auto;
border: 1px solid;
}
.child {
width: 500vw;
height: 500vh;
}
</style>
...
<body>
<div class="father">
<div class="child"></div>
</div>
</body>
所以先理清你的想法
- 同时监听父节点的mousedown事件和mousemove事件
- 当压力和移动同时触发时,计算 X 和 Y 移动的距离
- 将移动的距离应用到滚动面板
所以编码吧!
1。获取父元素节点
let father = document.querySelector('.father');
2。定义要使用的变量
// 判断鼠标是否按下
let isMouseDown = false;
// 记录Y轴滚动距离
let scrollTop = 0;
// 记录X轴滚动距离
let scrollLeft = 0;
// 记录鼠标落点X坐标
let startX = 0;
// 记录鼠标落点Y坐标
let startY = 0;
3。监听鼠标按下事件
father.addEventListener('mousedown', e => {
// 修改按下状态
isMouseDown = true;
// 记录按下鼠标的位置, 用于计算鼠标的移动距离
startX = e.offsetX;
startY = e.offsetY;
});
4。通过鼠标移动监听事件
father.addEventListener('mousemove', e => {
// 判断鼠标移动时是否处于按下状态
if (isMouseDown) {
// 获取鼠标按下后移动的距离
let offsetX = e.offsetX - startX;
let offsetY = e.offsetY - startY;
// PS: 需要注意的是当鼠标向上移动时, 滚动条应该向下移动, 所以这里都是减去的移动距离
scrollTop = scrollTop - offsetY;
scrollLeft = scrollLeft - offsetX;
// TODO
// 将计算后的距离赋值给滚动条
father.scrollTop = scrollTop;
father.scrollLeft = scrollLeft;
}
}
5。鼠标抬起时更改状态
father.addEventListener('mouseup', () => {
isMouseDown = false;
})
let father = document.querySelector('.father');
但是我们使用的时候很快就会发现一个问题,就是当滚动条移动到终点时,计算的距离会不断累加,结果是当累加距离超过限制时,向相反方向移动鼠标,滑块不会立即移动。所以编辑上面的代码
PS1:添加变量以计算步骤2中的边界距离
// 横向可移动的最大距离
let limitX = father.scrollWidth - father.offsetWidth;
// 纵向可移动的最大距离
let limitY = father.scrollHeight - father.offsetHeight;
PS2:在步骤 4 中添加评级
...
// TODO
if (scrollTop >= limitY) {
// 当滑块移动到底端时
scrollTop = limitY;
} else if (scrollTop <= 0) {
// 当滑块移动到顶端时
scrollTop = 0;
}
if (scrollLeft >= limitX) {
// 当滑块移动到左侧时
scrollLeft = limitX;
} else if (scrollLeft <= 0) {
// 当滑块移动到右侧时
scrollLeft = 0;
}
...
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。