记录–前端实现登录拼图验证

  • 记录–前端实现登录拼图验证已关闭评论
  • 115 次浏览
  • A+
所属分类:Web前端
摘要

不知各位朋友现在在web端进行登录的时候有没有注意一个变化,以前登录的时候是直接账号密码通过就可以直接登录,再后来图形验证码,数字结果运算验证,到现在的拼图验证。这一系列的转变都是为了防止机器操作,但对于我们来说,有亿点麻烦,但也没办法呀。


这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助

记录--前端实现登录拼图验证

前言

不知各位朋友现在在web端进行登录的时候有没有注意一个变化,以前登录的时候是直接账号密码通过就可以直接登录,再后来图形验证码,数字结果运算验证,到现在的拼图验证。这一系列的转变都是为了防止机器操作,但对于我们来说,有亿点麻烦,但也没办法呀。

今天我们也一起来做一个制造亿点麻烦的人,实现一个拼图验证。

实现原理

这个实现原理并不复杂,我们只需要一张图作为我们的拼接素材,我们再单独弄一个盒子,然后移动它,到我们的指定位置,到达指定范围内即验证通过,反之验证未通过。

既然原理我们知道了,那我们就开干吧。

实现前端登录拼图验证

本篇文章以 css 为主, javascript为辅实现。

搭建框架

我们要实现这个功能,我们需要先搭建出来一个框架。

// 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>

我们画出来后,它就长下面图这样。

记录--前端实现登录拼图验证

添加被校验区域及校验区域

我们需要添加一个被校验的区域及校验区域,用来做我们的校验,像下图这两个东西。

记录--前端实现登录拼图验证

这里我们使用伪类来实现这两个区域。

校验区域

    .check::before{             content: '';             width: 50px;             height: 50px;             background: rgba(0, 0, 0, 0.5);             border: 1px solid #fff;             position: absolute;             top: 100px;             left: 280px;     }

这样一个校验区域就做好了。

记录--前端实现登录拼图验证

被校验区域

这里我们需要使用到background-position根据我们的校验区域大小进行切出我们的被校验区域。

background-imagebackground-repeat我们直接继承,background-position设置为校验区域的坐标位置(也就是距离topleft的距离),我们将background-size图片大小设为原盒子的大小。这样我们就得到了校验区域的那一片区域,也就是我们的被校验区域了。

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

记录--前端实现登录拼图验证

添加拖动条

这里我们两个区域都添加完了,我们需要添加一个拖动条。

我们先添加一个拖动区域。

    // css     .drag{             width: 400px;             height: 50px;             background-color: #e3e3e3;             margin-top: 10px;             position: relative;     }          // html     <div class="drag"></div>

记录--前端实现登录拼图验证

现在拖动区域有了,我们需要在拖动区域内添加一个可拖动的盒子,及操作说明,不然看起来交互效果不友好。

添加可拖动的盒子及交互说明

我们添加一个可以拖动的盒子。

    // 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>

记录--前端实现登录拼图验证

 为了我们友好的交互,我们在拖动区域内给他添加操作说明。

    // 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>

记录--前端实现登录拼图验证

拖动条动起来

这一步我们需要让我们的拖动盒子动起来,让他可以在拖动区域内随意的左右拖动。

    // 获取元素实例     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)

现在我们的盒子就可以正常的拖动了,但现在它还有几个问题,我们后面来解决。

  1. 提示文字会被选中;
  2. 拖动区域内拖动会闪烁;

联动被校验区域

我们先让被校验区域跟着我们的拖动动起来。

    // 图形校验     const check = document.querySelector('.check-child')          // 修改被校验区域坐标     check.style.left = `${offsetX}px`

这样我们的被校验区域就能够跟着动了,我们声明一个方法用来表示,通过校验的回调。

    // 通过校验回调     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()         }     }

记录--前端实现登录拼图验证

添加交互动画

这里我们在鼠标移出监听的时候添加一个动画,当当前未通过校验的时候我们给他还原到初始位置。

@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)         }     }

当我们未通过校验,且放开鼠标的时候,它就会自动回到初始位置。

解决遗留问题

1、 提示文字会被选中

我们在提示文字的样式中添加user-select: none;,禁用掉文字选择。

    /* 提示文字说明 */     .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、 在拖动区域内拖动会闪烁

我们将我们刚刚使用的offsetX改为pageX。这里需要注意一下边距偏移量的问题哦。

    // 监听鼠标移动事件     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)         }     }

效果图

我们看一下效果图。

记录--前端实现登录拼图验证

完整代码

<!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>

本文转载于:

https://juejin.cn/post/7175818459379417146

如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

 记录--前端实现登录拼图验证