foreword
I don’t know if my friends web
have noticed a change when logging in on the terminal. Before logging in, you can log in directly after passing the account and password, and then you can log in directly with the graphic verification code, the numerical result operation verification, and now the puzzle verification. This series of changes is to prevent machine operation, but for us, there are hundreds of millions of troubles, but there is no way.
Today we will also be a person who creates billions of troubles and realizes a jigsaw verification.
Realization principle
The implementation principle is not complicated. We only need a picture as our splicing material. We will make a separate box, and then move it to our specified position. If it reaches the specified range, the verification will pass. Otherwise, the verification will not pass.
Now that we know the principle, let's get started.
Implement front-end login puzzle verification
This article is css
mainly based on and javascript
supplemented by realization.
Build the framework
To achieve this function, we need to build a framework first.
// css
<style>
.check{
width: 400px;
height: 300px;
background-repeat: no-repeat;
background-size: 100% 100%;
background-image: url(https://img0.baidu.com/it/u=2028084904,3939052004&fm=253&fmt=auto&app=138&f=JPEG?w=889&h=500);
}
</style>
// html
<div class="check"></div>
After we draw it, it will look like the picture below.
Add the area to be verified and the area to be verified
We need to add a verified area and a verified area for our verification, as shown in the figure below.
Here we use pseudo-classes to implement these two areas.
check area
.check::before{
content: '';
width: 50px;
height: 50px;
background: rgba(0, 0, 0, 0.5);
border: 1px solid #fff;
position: absolute;
top: 100px;
left: 280px;
}
Such a verification area is ready.
Checked area
Here we need to background-position
cut out our verified area according to the size of our verification area.
background-image
Inherit directly with background-repeat
us, background-position
set it as the coordinate position of the verification area (that is, the distance between the sum top
and left
the distance), and we set background-size
the size of the picture to the size of the original box. In this way, we get the area of the verification area, which is our area to be verified.
.check-child{
content: '';
width: 50px;
height: 50px;
border: 1px solid #fff;
background-image: inherit;
background-repeat: inherit;
background-size: 400px 300px;
background-position: -280px -100px;
position: absolute;
top: 100px;
left: 10px;
}
// html
<!-- 被校验区域 -->
<div class="check-child"></div>
add drag bar
Here we have finished adding both areas, we need to add a drag bar.
Let's start by adding a drag zone.
// css
.drag{
width: 400px;
height: 50px;
background-color: #e3e3e3;
margin-top: 10px;
position: relative;
}
// html
<div class="drag"></div>
Now that the drag area is available, we need to add a draggable box and operation instructions in the drag area, otherwise the interaction effect will look unfriendly.
Add draggable boxes and interactive instructions
We add a draggable box.
// css
.drag-child{
width: 50px;
height: 50px;
background-color: aquamarine;
z-index: 10;
position: absolute;
top: 0;
left: 0;
}
// html
<!-- 可拖动的盒子 -->
<div class="drag-child"></div>
For our friendly interaction, we add operation instructions to him in the drag area.
// css
.drag-tips{
display: flex;
align-items: center;
justify-content: end;
width: 95%;
height: 100%;
margin: 0 auto;
font-size: 12px;
color: #8a8a8a;
}
// html
<!-- 可拖动的盒子 -->
<div class="drag-tips">
<span>按住左边按钮向右拖动完成上方图像验证</span>
</div>
Drag the bar to move
In this step, we need to make our drag box move, so that he can drag left and right in the drag area at will.
// 获取元素实例
const drag = document.querySelector('.drag-child')
// 声明鼠标按下事件
const dragMouseDown = event => {
// 添加鼠标移动事件
document.addEventListener('mousemove', dragMouseMove)
}
// 监听鼠标移动事件
const dragMouseMove = event => {
// 获取当前 x 轴坐标
const {
offsetX } = event
if(offsetX < 0 || offsetX > 350){
return
}
// 修改可移动盒子的 x 轴坐标
drag.style.transform = `translateX(${
offsetX}px)`
}
// 结束鼠标监听事件
const dragMouseUP = event => {
// 移除鼠标移动事件
document.removeEventListener('mousemove', dragMouseMove)
}
// 添加鼠标按下事件
document.addEventListener('mousedown', dragMouseDown)
// 添加鼠标弹起事件
document.addEventListener('mouseup', dragMouseUP)
Now our box can be dragged normally, but it still has a few problems, which we will solve later.
- The prompt text will be selected;
拖动区域
Dragging inside
Linkage area to be verified
Let's make the checked area move with our dragging.
// 图形校验
const check = document.querySelector('.check-child')
// 修改被校验区域坐标
check.style.left = `${
offsetX}px`
In this way, our verified area can move accordingly, and we declare a method to indicate that the verification callback is passed.
// 通过校验回调
const success = () => {
console.log('通过校验');
}
// 监听鼠标移动事件
const dragMouseMove = event => {
// 获取当前 x 轴坐标
const {
offsetX } = event
if(offsetX < 0 || offsetX > 350){
return
}
// 修改可移动盒子的 x 轴坐标
drag.style.transform = `translateX(${
offsetX}px)`
// 修改被校验区域坐标
check.style.transform = `translateX(${
offsetX}px)`
if(offsetX >= 278 && offsetX <= 285){
// 执行回调
success()
}
}
Add interactive animation
Here we add an animation when the mouse moves out of the monitor, and we restore it to its initial position when the current verification fails.
@keyframes move {
to {
transform: translateX(0);
}
}
// 结束鼠标监听事件
const dragMouseUP = event => {
// 移除鼠标移动事件
document.removeEventListener('mousemove', dragMouseMove)
// 获取当前 x 轴坐标
const {
offsetX } = event
if(offsetX < 278 || offsetX > 285){
// 修改可移动盒子的 x 轴坐标
drag.style.animation = 'move 0.5s ease-in-out'
// 修改被校验区域坐标
check.style.animation = 'move 0.5s ease-in-out'
// 动画结束监听回调
const animationEnd = ()=>{
// 修改可移动盒子的 x 轴坐标
drag.style.transform = `translateX(${
0}px)`
// 修改被校验区域坐标
check.style.transform = `translateX(${
0}px)`
// 清除动画属性
drag.style.animation = ''
check.style.animation = ''
// 移出动画结束监听
document.removeEventListener("animationend", animationEnd)
}
// 添加动画结束监听
document.addEventListener("animationend", animationEnd)
}
}
When we fail the validation and let go of the mouse, it will automatically return to the initial position.
solve legacy problems
1. The prompt text will be selected
We add it to the style of the prompt text user-select: none;
and disable the text selection.
/* 提示文字说明 */
.drag-tips{
display: flex;
align-items: center;
justify-content: end;
width: 95%;
height: 100%;
margin: 0 auto;
font-size: 12px;
color: #8a8a8a;
user-select: none;
z-index: 1;
position: absolute;
top: 0;
left: 0;
}
2. Dragging 拖动区域
inside will flash
We offsetX
change what we just used to pageX
. Here you need to pay attention to the issue of margin offset.
// 监听鼠标移动事件
const dragMouseMove = event => {
console.log(event);
// 获取当前 x 轴坐标
const {
pageX } = event
if(pageX < 0 || pageX > 350){
return
}
// 修改可移动盒子的 x 轴坐标
drag.style.transform = `translateX(${
pageX}px)`
// 修改被校验区域坐标
check.style.transform = `translateX(${
pageX}px)`
if(pageX >= 278 && pageX <= 285){
// 执行回调
success()
}
}
// 结束鼠标监听事件
const dragMouseUP = event => {
// 移除鼠标移动事件
document.removeEventListener('mousemove', dragMouseMove)
// 获取当前 x 轴坐标
const {
pageX } = event
if(pageX < 278 || pageX > 285){
// 修改可移动盒子的 x 轴坐标
drag.style.animation = 'move 0.5s ease-in-out'
// 修改被校验区域坐标
check.style.animation = 'move 0.5s ease-in-out'
// 动画结束监听回调
const animationEnd = ()=>{
// 修改可移动盒子的 x 轴坐标
drag.style.transform = `translateX(${
0}px)`
// 修改被校验区域坐标
check.style.transform = `translateX(${
0}px)`
// 清除动画属性
drag.style.animation = ''
check.style.animation = ''
// 移出动画结束监听
document.removeEventListener("animationend", animationEnd)
}
// 添加动画结束监听
document.addEventListener("animationend", animationEnd)
}
}
renderings
Let's take a look at the renderings.
full code
<!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>drag</title>
<style>
*{
margin: 0;
padding: 0;
}
body{
padding: 20px;
}
/* 图形拼图验证码 */
.check{
width: 400px;
height: 300px;
background-repeat: no-repeat;
background-size: 100% 100%;
background-image: url(https://img0.baidu.com/it/u=2028084904,3939052004&fm=253&fmt=auto&app=138&f=JPEG?w=889&h=500);
position: relative;
}
.check::before{
content: '';
width: 50px;
height: 50px;
background: rgba(0, 0, 0, 0.5);
border: 1px solid #fff;
position: absolute;
top: 100px;
left: 280px;
}
.check-child{
content: '';
width: 50px;
height: 50px;
border: 1px solid #fff;
background-image: inherit;
background-repeat: inherit;
background-size: 400px 300px;
background-position: -280px -100px;
position: absolute;
top: 100px;
left: 0;
}
/* 拖动条 */
.drag{
width: 400px;
height: 50px;
background-color: #e3e3e3;
margin-top: 10px;
position: relative;
}
/* 可拖动的盒子 */
.drag-child{
width: 50px;
height: 50px;
background-color: aquamarine;
z-index: 10;
position: absolute;
top: 0;
left: 0;
}
/* 提示文字说明 */
.drag-tips{
display: flex;
align-items: center;
justify-content: end;
width: 95%;
height: 100%;
margin: 0 auto;
font-size: 12px;
color: #8a8a8a;
user-select: none;
z-index: 1;
position: absolute;
top: 0;
left: 0;
}
@keyframes move {
to {
transform: translateX(0);
}
}
</style>
</head>
<body>
<!-- 图形校验区域 -->
<div class="check">
<!-- 被校验区域 -->
<div class="check-child"></div>
</div>
<!-- 拖动条 -->
<div class="drag">
<!-- 操作说明 -->
<div class="drag-tips">
<span>按住左边按钮向右拖动完成上方图像验证</span>
</div>
<!-- 可拖动的盒子 -->
<div class="drag-child"></div>
</div>
</body>
<script>
// 获取元素实例
const drag = document.querySelector('.drag-child')
// 图形被校验区域
const check = document.querySelector('.check-child')
// 通过校验回调
const success = () => {
console.log('通过校验');
}
// 声明鼠标按下事件
const dragMouseDown = event => {
// 添加鼠标移动事件
document.addEventListener('mousemove', dragMouseMove)
}
// 监听鼠标移动事件
const dragMouseMove = event => {
// 获取当前 x 轴坐标
const {
pageX } = event
if(pageX < 0 || pageX > 350){
return
}
// 修改可移动盒子的 x 轴坐标
drag.style.transform = `translateX(${
pageX}px)`
// 修改被校验区域坐标
check.style.transform = `translateX(${
pageX}px)`
if(pageX >= 278 && pageX <= 285){
// 执行回调
success()
}
}
// 结束鼠标监听事件
const dragMouseUP = event => {
// 移除鼠标移动事件
document.removeEventListener('mousemove', dragMouseMove)
// 获取当前 x 轴坐标
const {
pageX } = event
if(pageX < 278 || pageX > 285){
// 修改可移动盒子的 x 轴坐标
drag.style.animation = 'move 0.5s ease-in-out'
// 修改被校验区域坐标
check.style.animation = 'move 0.5s ease-in-out'
// 动画结束监听回调
const animationEnd = ()=>{
// 修改可移动盒子的 x 轴坐标
drag.style.transform = `translateX(${
0}px)`
// 修改被校验区域坐标
check.style.transform = `translateX(${
0}px)`
// 清除动画属性
drag.style.animation = ''
check.style.animation = ''
// 移出动画结束监听
document.removeEventListener("animationend", animationEnd)
}
// 添加动画结束监听
document.addEventListener("animationend", animationEnd)
}
}
// 添加鼠标按下事件
document.addEventListener('mousedown', dragMouseDown)
// 添加鼠标弹起事件
document.addEventListener('mouseup', dragMouseUP)
</script>
</html>
at last
This is the end of this article 前端实现登录拼图验证
. This function is generally used when logging in. The case in this article can be used normally.
There is a legacy problem in the code implemented in this article, which can be dragged in the non-dragging area.