Front-end implementation of login puzzle verification

insert image description here

foreword

I don’t know if my friends webhave 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 cssmainly based on and javascriptsupplemented 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.

image.png

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.

image.png

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.

image.png

Checked area

Here we need to background-positioncut out our verified area according to the size of our verification area.

background-imageInherit directly with background-repeatus, background-positionset it as the coordinate position of the verification area (that is, the distance between the sum topand leftthe distance), and we set background-sizethe 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>

image.png

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>

image.png

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>

image.png

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>

image.png

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.

  1. The prompt text will be selected;
  2. 拖动区域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()
        }
    }

image.png

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 offsetXchange 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.

image.png

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.

Guess you like

Origin blog.csdn.net/qq_44500360/article/details/128276617