前言:
使用技术:
需要的理论:
- 需要使用
js
绑定onmousedown
事件进行监听本次滑动开始的状态信息,并且判断记录当前鼠标位置,以便后续的移动,并且设置可移动flag
为true
。 - 在绑定
js
中的onmousemove
事件进行监听移动事件,(注意这个事件会根据移动调用n次,可能会出现性能问题,所以需要加入节流或防抖),当可移动flag
为true
,获取每次移动的状态信息,然后根据上述鼠标位置进行计算,得到最终偏移量。 - 最后需要在
js
中去绑定onmouseup
事件来结束移动事件,按照最终计算值来判断是否这次验证移动是否成功,如果未成功直接回到初始状态,如果成功则显示成功状态,并修改已验证flag
。会存在的问题:
如果把事件全绑定到滑块》上,如果是慢慢滑动不会出现问题,极端问题就是,使用者非常迅速的滑动会导致失去焦点,无法再滑动,必须要进入滑块的焦点中才能继续滑动。解决方案:
前端代码:
js代码: ```html siderMouseUpEvent (e) { if (this.sliderMoveX<270) {<div class="verify-silder-box">
<div :style="{width: sliderMoveX +5+'px'}" class="green-bar"></div>
<div :style="{transform: 'translateX('+sliderMoveX+'px)'}" class="silder" @mousedown="siderMouseDownEvent" @mouseup="siderMouseUpEvent">
<i class="el-icon-d-arrow-right"></i>
</div>
<p class="slider-tips-txt">{{sliderMoveX === 0 ? '滑动验证' : isverifyFlag ?"通过":""}}</p>
</div>
} this.lockSlider = false; }, siderMouseDownEvent (e) { if (!this.isverifyFlag) {this.sliderMoveX = 0;
} // 绑定mousemove事件到document上是为了拖拽太快失去了当前元素的焦点 导致卡顿 document.onmousemove = ev => {this.lockSlider = true;
this.initX = e.screenX;
this.sliderMoveX = 0;
}if (this.lockSlider) {
var ww = document.documentElement.clientWidth;
var wh = window.innerHeight;
var event = ev || window.event;
var scrolltop = document.documentElement.scrollTop || document.body.scrollTop;
if (event.clientY < 0 || event.clientX < 0 || event.clientY > wh || event.clientX >
ww) {
return false;
};
var endx = event.clientX - this.initX;
if (endx >=0 && endx<270) {
this.sliderMoveX = endx;
} else if (endx>=270) {
this.sliderMoveX = 270;
this.lockSlider = false;
this.isverifyFlag = true;
}
}
解决原理:
其实看上述代码就能看得出,对于滑块的事件绑定只绑定了两个,一个是onmousedown
事件,这个事件记录鼠标当前位置和启动可以移动的标志位lockSlider
;另一个是onmouseup
事件,这个事件是为了关闭可以滑动的状态,并且根据滑动的信息判断是否验证成功。而在这个onmousedown
事件中,加上了一个监听document
上的onmousemove
的事件,这里是最主要的为了解决失去滑动元素焦点导致无法进行滑动的问题。当把移动事件绑定到了document
上之后就形成了全局滑动的事件,这样就不会导致某个元素失去焦点的问题,而是记录在document
上的偏移量。