原生js实现拖动滑块验证题
前言
验证的目的是为了减轻超高数据量的访问时,服务器的压力,减少同时请求量;前端基本都不能避免与验证打交道,这里记录一下我对于滑块验证的学习过程。
思路
作为前端,我们要将自己带入用户的角度,对用户的操作习惯进行考虑,我将拖动滑块验证功能归纳为:三个事件、验证成功、验证失败。
- 按住滑块才能开始拖动(按下、移动、松开事件)
- 验证成功后不能再拖动(跳转页面或禁用)
- 验证失败时,滑块回归原始位置(拖动到一半松开)
代码结构
HTML结构:box -> 滑块+文字+背景
滑块移动思路
box position:relative
滑块 position:absolute
-
拖动滑块,让滑块的绝对定位left随鼠标坐标而改变,造成移动效果
通过evevt事件可以获取到当前X轴和Y轴坐标,event.clientX;clientY
event.clientX;clientY 是从屏幕左上角开始的坐标
滑块移动距离(left) = 用移动时鼠标的坐标 - 最开始鼠标按下的坐标
clipboard.png -
控制滑块移动的范围,不超出box
clipboard2.png
(moveX >= 0 && moveX <= (boxWidth - btnWidth)
btn.style.left = (boxWidth - btnWidth) + 'px'
滑块可移动的范围moveX如图所示,在0到(box的宽度 - 滑块的宽度)之间
-
滑动途中,背景的宽度改变
背景的宽度与滑块可移动范围moveX相同
bg.style.width = (boxWidth - btnWidth) + 'px'
-
滑动到尾部时要文字替换+事件清除(按下、移动、松开)
-
鼠标松开,滑块回到原点,清除移动事件(不清除按下事件,否则之后不能按下)
最后上代码
HTML
<div class="box">
<div class="btn">>></div>
<p class="text">拖动滑块验证</p>
<div class="bg"></div>
</div>
CSS
* {
margin: 0;
padding: 0;
background-color: #ffffff;
}
.box {
width: 500px;
height: 60px;
position: relative;
left: 50%;
margin-left: -250px;
margin-top: 50px;
background: #eae4e4;
display: flex;
align-items: center;
-webkit-user-select:none;
-moz-user-select:none;
-ms-user-select:none;
user-select:none;
}
.btn {
height: 100%;
width: 60px;
background: #fbf5f5;
box-sizing: border-box;
border: 2px solid #cecaca;
position: absolute;
left: 0;
top: 0;
display: flex;
align-items: center;
justify-content: center;
font-size: 25px;
color: #d5d4d4;
z-index: 999;
-webkit-user-select:none;
-moz-user-select:none;
-ms-user-select:none;
user-select:none;
}
.btn:hover {
cursor:pointer;
}
.text {
font-size: 20px;
position: absolute;
left: 50%;
margin-left: -60px;
background-color: transparent;
z-index: 2;
}
.bg {
height: 100%;
position: absolute;
background-color: #4cbb42;
z-index: 1;
}
JS
window.onload = function () {
// 封装-选择器,内部可以做兼容性
function querySelect(name) {
return document.querySelector(name)
}
// 验证成功
// 验证失败
// 触发事件 onmousedown按下 onmousemove移动 onmouseup松开
let btn = querySelect('.btn') // 滑块 对IE6/7 有兼容性问题
let box = querySelect('.box') // box
let text = querySelect('.text') // 文字
let bg = querySelect('.bg') // 背景
btn.onmousedown = (eventDown) => {
// event.clientX;clientY 鼠标当前X轴Y轴坐标
let downX = eventDown.clientX
console.log(downX)
document.onmousemove = (eventMove) => {
// 移动的X坐标 - 按下的X坐标
let moveX = eventMove.clientX - downX
let boxWidth = box.offsetWidth
let btnWidth = btn.offsetWidth
if (moveX >= 0 && moveX <= (boxWidth - btnWidth)) { // 可移动的范围
btn.style.left = moveX + 'px' // 滑块绝对定位
bg.style.width = moveX + 'px' // 设备背景的宽度
}
if (moveX >= (boxWidth - btnWidth)) {
btn.style.left = (boxWidth - btnWidth) + 'px' // 滑块绝对定位
bg.style.width = (boxWidth - btnWidth) + 'px' // 设备背景的宽度
// 文字提醒
text.innerText = '验证成功'
text.style.color = '#fff'
// 事件清除-按下、移动
btn.onmousedown = null
document.onmousemove = null
btn.onmouseup = null
}
}
}
btn.onmouseup = (eventUp) => {
// 松开后回到原点
// 清除移动事件
btn.style.left = 0 + 'px'
bg.style.width = 0 + 'px'
document.onmousemove = null
}
}
网友评论