前言:
之前练习阴阳师网页时,有如下的效果要实现,答主在网上找了很多教程,最后参考了某一篇博客写出,时间已久,忘记该博客地址。如有侵权,定及时删除!
正文:
对于以上的效果,我们可以先来分析下,涉及的事件有 鼠标按下(onmousedown),鼠标移动onmousemove),鼠标释放(onmouseup),鼠标滑动(onmousewheel)
那么我们可以想一想:当鼠标按下的时候,我们是不是可以触发开关,让内容睡着滑块移动,当鼠标释放的时候,关闭开关。则内容也暂停移动。
好了,下面我们来看下代码:
HTML:
<div class="line_div"> //轨道
<div class="hua_div"></div> //滑块
</div>
CSS:
.line_div{
position:relative;
width: 1200px;
height: 20px;
margin:0 auto;
border-radius:50%;
background:gray;
}
.hua_div{
position:absolute;
left:0;
top:-10px;
width: 100px;
height: 30px;
background:red;
}
JS:
var line = document.querySelector('.line_div'); //获取进度条
var hua = document.querySelector('.hua_div'); //滑块
var _status = false; //状态开关
好了,我们已经设置过开关flag了,那么根据上面的要求,我们可以在鼠标按下的时候触发开关,鼠标释放的时候关闭开关。
var start = function(ev){ //开启状态
var e = ev || window.event;
_status = true;
console.log("鼠标按下");
}
var over = function(ev){ //结束状态
var e = ev || window.event;
_status = false;
console.log("鼠标释放");
}
那么,我们知道开关开启后,我们是不是就可以拖动滑块来实现我们想要的效果了,那么大家想一想怎样让滑块跟着我们的鼠标移动而移动,从而实现拖动的效果呢 ?
是不是只需要让鼠标到距离减去滑块到页面的距离就可以了呢,没错,这个差值就是滑块需要移动的距离
那么我们该如何求这个差值呢,不要着急,我们一步一步来,先来求滑块距离页面的距离。下面我先放下代码。这部分代码用来求滑块到页面的距离:
// 获取长条距离方法
function getPosition(node){
var left = node.offsetLeft;
var top = node.offsetTop;
var current = node.offsetParent;//获取离node最近的开启定位的元素
while(current != null){
left += current.offsetLeft;
top += current.offsetTop;
current = current.offsetParent;
}
return { //返回对象类型
"left":left,
"top":top
}
}
如果getPosition()函数里传入的是轨道元素。那么我们首先就获得了轨道line距离页面的左距离以及上距离。而 var current = node.offsetParent;//获取离node最近的开启定位的元素,这里我们获取的是滑块hua元素。那么left += current.offsetLeft;我们就获得了滑块+轨道的距离,也就是说我们获取了滑块距离页面的距离
接下来我们就可以写最核心的移动代码了:
var run = function(ev){//运行状态
var e = ev || window.event;
var dis = e.clientX; //获取鼠标到页面的距离
if(_status){
console.log("鼠标移动");
var lineLeft = getPosition(line).left; //获取滑块到页面的距离
var huaLeft = dis - lineLeft; //获得差值,也就是滑块要移动的距离
if(huaLeft >= line.offsetWidth - hua.offsetWidth){//滑块越界处理
huaLeft = line.offsetWidth - hua.offsetWidth;
}
if(huaLeft < 0){ //滑到头部外面,越界处理
huaLeft = 0;
}
hua.style.left = huaLeft + "px"; //设置滑块的left距离
console.log(huaLeft);
}
}
最后給鼠标移动事件调用这个移动函数即可
window.addEventListener('mousemove',run);
那么到这里我们就完成了滑块的拖动,那么如何滚动滑轮使得滑块移动呢,其实我们只需要給轨道添加滑动事件onmousewheel事件即可,为什么要給轨道添加而不是給滑块添加呢。大家想一想如果滑块添加,那么当我们触发滑动事件时,鼠标的位置是不是要一直位于滑块上才可以。这样做并不方便。那么如果我们給轨道添加滑动事件,这样鼠标只要位于轨道上就可以触发滑动事件,从而使得滑块移动。
// 鼠标滚动
var index = 0;
line.addEventListener('mousewheel',function(ev){
if(e.wheelDelta > 0){
hua.style.left = (--index)*20 + "px";
console.log("1:"+index);
}
if(e.wheelDelta < 0){
hua.style.left = (++index)*20 + "px";
console.log("2:"+index);
}
})
如果大家对于滑动事件的wheelDelta参数不了解得话可以去查一下,这里博主就不过多介绍了。这里呢博主采取得是每次移动20像素,如果有其他需要得小伙伴可自行在滑轮事件里添加自己想要实现得功能。
好了,下面放一下完整版代码:
<!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>拖动练习</title>
<style>
.line_div{
position:relative;
width: 1200px;
height: 20px;
margin:0 auto;
border-radius:50%;
background:gray;
}
.hua_div{
position:absolute;
left:0;
top:-10px;
width: 100px;
height: 30px;
background:red;
}
</style>
</head>
<body>
<div class="line_div">
<div class="hua_div"></div>
</div>
<script>
var line = document.querySelector('.line_div'); //获取进度条
var hua = document.querySelector('.hua_div'); //滑块
var _status = false; //状态开关
var index = 0;
var start = function(ev){ //开启状态
var e = ev || window.event;
_status = true;
console.log("鼠标按下");
}
var over = function(ev){ //结束状态
var e = ev || window.event;
_status = false;
console.log("鼠标抬起");
}
var run = function(ev){//运行状态
var e = ev || window.event;
var dis = e.clientX;
if(_status){
console.log("鼠标移动");
var lineLeft = getPosition(line).left; //获取滑块的长度
var huaLeft = dis - lineLeft;
if(huaLeft >= line.offsetWidth - hua.offsetWidth){//滑块越界处理
huaLeft = line.offsetWidth - hua.offsetWidth;
}
if(huaLeft < 0){
huaLeft = 0;
}
hua.style.left = huaLeft + "px";
console.log(huaLeft);
}
}
// 获取长条距离方法
function getPosition(node){
var left = node.offsetLeft;
var top = node.offsetTop;
var current = node.offsetParent;//获取离node最近的开启定位的元素
while(current != null){
left += current.offsetLeft;
top += current.offsetTop;
current = current.offsetParent;
}
return { //返回对象类型
"left":left,
"top":top
}
}
// 鼠标滚动
line.addEventListener('mousewheel',function(ev){
if(e.wheelDelta > 0){
hua.style.left = (--index)*20 + "px";
}
if(e.wheelDelta < 0){
hua.style.left = (++index)*20 + "px";
}
})
hua.addEventListener('mousedown',start);
window.addEventListener('mousemove',run);
window.addEventListener('mouseup',over);
</script>
</body>
</html>
答主这个效果有个bug就是滑轮事件没有和拖动事件关联起来,在用户拖动到某位置时,如果切换到滑轮滚动时,并没有从暂停得位置开始滚动,而是从头开始滚动。
如果有解决得办法,请在评论区提点答主,谢谢啦