最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

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

来源:博客园

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

前言

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

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

实现原理

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


(资料图)

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

实现前端登录拼图验证

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

搭建框架

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

// css// html

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

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

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

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

校验区域

.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            

添加拖动条

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

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

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

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

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

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

// css        .drag-child{        width: 50px;        height: 50px;        background-color: aquamarine;        z-index: 10;        position: absolute;        top: 0;        left: 0;    }        // html            

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

// css        .drag-tips{        display: flex;        align-items: center;        justify-content: end;        width: 95%;        height: 100%;        margin: 0 auto;        font-size: 12px;        color: #8a8a8a;    }        // html            
按住左边按钮向右拖动完成上方图像验证

拖动条动起来

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

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

效果图

我们看一下效果图。

完整代码

                drag            
按住左边按钮向右拖动完成上方图像验证
<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>

本文转载于:

https://juejin.cn/post/7175818459379417146

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

关键词: 鼠标移动 我们需要 鼠标按下