目录 前言 核心功能 实现原理 实现前端登录拼图验证 搭建框架 添加被校验区域及校验区域 添加滑块、滑块背景、拖动条、提示文字 添加交互 联动被校验区域 随机生成校验位置 完整
目录
- 前言
- 核心功能
- 实现原理
- 实现前端登录拼图验证
- 搭建框架
- 添加被校验区域及校验区域
- 添加滑块、滑块背景、拖动条、提示文字
- 添加交互
- 联动被校验区域
- 随机生成校验位置
- 完整代码
- 总结
前言
不知各位朋友现在在 web 端进行登录的时候有没有注意一个变化,以前登录的时候是直接账号密码通过就可以直接登录,再后来图形验证码,数字结果运算验证,到现在的拼图验证。这一系列的转变都是为了防止机器操作,但对于我们来说,有亿点麻烦,但也没办法呀。
今天我们也一起实现一个拼图验证。
核心功能
- 滑动解锁功能
- 重置位置功能
- 滑块进度条功能
- 结果提示功能
- 随机生成滑块位置
实现原理
这个的实现原理并不复杂,我们只需要一张背景图作为我们的拼接素材,再单独定义一个盒子并拖拽移动它到指定位置就可以完成拼图验证功能了
实现前端登录拼图验证
搭建框架
我们要实现这个功能,我们需要先搭建出来一个样式结构出来。
// css
:root {
--iWidth: 50px;
--iHeight: 50px;
}
.wrapper {
width: 100%;
width: 500px;
margin: 0 auto;
}
.container {
position: relative;
width: 500px;
height: 300px;
box-shadow: 0px 2px 4px 0px rgba(0,0,0,0.5);
border-radius: 8px;
background-image: url("./bg.webp");
background-size: 100% 100%;
background-repeat: no-repeat;
}
// html
<div class="wrapper">
<!-- 容器 -->
<div class="container"></div>
</div>
我们根据刚才的样式结构搭建完成后,它就长下图这个样子

添加被校验区域及校验区域
我们需要添加一个被校验区域及校验区域,用来做我们的滑动校验
!!在滑动区域中使用 background-position 配合 background-size 根据校验区域的大小和位置切出滑动区域的图
// css
// 被校验区域样式
.container-move {
position: absolute;
width: var(--iWidth);
height: var(--iHeight);
top: 180px;
left: 0;
z-index: 3;
background-size: 500px 300px;
background-repeat: no-repeat;
background-image: url("./img/bg.jpg");
background-position: -180px -200px;
}
// 校验区域样式
.container-empty {
position: absolute;
width: var(--iWidth);
height: var(--iHeight);
top: 180px;
left: 200px;
background: #fff;
z-index: 2;
opacity: .6;
}
// html
<div class="wrapper">
<!-- 容器 -->
<div class="container">
<!-- 被校验区域 -->
<div class="container-move"></div>
<!-- 校验区域 -->
<div class="container-empty"></div>
</div>
</div>
效果图

添加滑块、滑块背景、拖动条、提示文字
拖动条来控制滑块移动的最大距离
滑块来控制被校验区域的移动距离
提示文字是提示用户这里可以操作解锁
拖动条内的滑块、滑块背景、提示文字都对拖动条进行绝对定位
主要是为了控制他们的层级,提示文字 < 滑块背景 < 滑块
我们添加滑块、滑块背景、拖动条、提示文字
// css
/* 拖动条样式 */
.slider-control {
width: 500px;
height: 50px;
margin-top: 20px;
border-radius: 4px;
position: relative;
overflow: hidden;
background: #f2f2f2;
box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.5);
}
/* 滑块 */
.slider {
width: var(--iWidth);
height: var(--iHeight);
position: absolute;
left: 0;
top: 0;
background: skyblue;
border-radius: 4px;
text-align: center;
line-height: var(--iHeight);
transition: all;
user-select: none;
z-index: 3;
}
/* 滑块背景 */
.slider-shadow {
position: absolute;
left: 0;
top: 0;
width: 0;
height: 50px;
background: #fff;
z-index: 2;
}
/* 提示文案 */
.slider-info {
text-align: center;
color: rgba(102, 102, 102, 1);
margin: 0;
line-height: 50px;
}
// html
<div class="wrapper">
<!-- 控制容器 -->
<div class="slider-control">
// 提示文字
<p class="slider-info">按住左边按钮向右拖动完成上方图像验证</p>
// 滑块
<div class="slider">>></div>
// 滑块背景
<div class="slider-shadow"></div>
</div>
</div>
效果图如下

添加交互
到这里拼图验证的样式结构已经完成了,接下来我们需要对相关的元素添加交互事件
让滑块可以在拖动条内随意拖拽
// 我太懒了,不想写那么一大堆,这里封装个用 class 来获取实例的函数
function getElement(elName) {
return document.getElementsByClassName(elName)[0]
}
// 获取实例
let sliderBox = getElement('slider'); // 滑动的块
let sliderShadow = getElement('slider-shadow'); // 滑动背景
let container = getElement("container"); // 容器的实例
let sliderMove = getElement("container-move"); // 解锁的块
let containerWidth = container.clientWidth; // 获取容器的可视区宽度
let sliderMoveWidth = sliderMove.clientWidth; // 被校验区域的可视区宽度
let maxDistance = (containerWidth - sliderMoveWidth); // 根据容器和被校验区域的大小限制滑块移动最大的距离
/**
* 监听鼠标在sliderBox(滑动块)按下时 mousedowm, 并根据可视区左边的距离减去鼠标按下的距离, 获取到实际
* document的onmouseMove和mouseup事件,
* 获取鼠标滑动的位置
*/
sliderBox.onmousedown = function (moveStart) {
// console.log(" 