文章目录
- 日常我们经常能见到验证码,网站上的验证码的作用是保护网站安全,一般网站都要通过验证码来防止机器大规模注册等危害。一般验证码有:图像验证、算数验证、滑动验证等。有些验证码验证起来有些麻烦,对我来说,最方便的验证方式是滑动滑块验证,滑块验证的使用体验非常好。 所以本篇文章我来尝试着实现一个滑动验证码。当然,这种验证码一般都是第三方来处理的,因为它不仅仅只是滑动,还会判断用户的拖放轨迹是否符合真实用户的行为特征,所以我只是简单的实现。
- 这是一个滑块验证码,用户只需要将滑块滑到最右侧,即可判断用户是否验证成功。
- 我为滑块验证添加了验证条件,用户可以对滑块速度做限制,例如:滑块滑倒右侧时,平均速度小于3,如果用户滑动速度大于3时,就验证失败。 我一共滑动了三次: 第一次:没有滑倒最右侧,认证失败。 第二次:滑动的速度太块,认证失败。 第三次:滑动速度符合限制,认证成功。
-
- 首先,我们需要在组件加载完成时,获取到滑块可以滑动的最大距离,我们用得到的最大距离,来判断滑块是否滑倒最右侧 注意组件的生命周期,在自定义组件中,是没有onShow的,需要用onLayoutReady(),这个钩子函数是自定义组件布局完成调用的。 然后,在触摸屏幕事件中,获取触摸的X坐标,此坐标为起始点;在触摸移动事件中,获取最新的X坐标,再减去起始坐标,就能得到偏移量。 最后,判断偏移量是否大于滑块可以滑动的最大距离,如果不大于,将偏移量设置为滑块的滑动距离。 为了更好理解,我把滑块隐藏部分显示出来。 touchstart (e) { //设置X轴的始点 this.startPositionX = e.touches[0].localX; this.startTime = 0 this.s = 0 this.num = 0 }, //滑块移动中执行的事件 touchmove (e) { const offsetX = e.touches[0].localX - this.startPositionX // 如果验证成功后仍允许滑动,则执行下面代码块(初始值默认为允许) if (this.isSlide) { //当x坐标大于最大可移动距离,那么当前x坐标即为最大可移动距离 if (offsetX >= this.max) { this.x = this.max } else { // 将当前鼠标x坐标给滑块移动的距离 this.x = offsetX; } } },
- 这里的验证不严谨,只是一个小尝试。 验证原理主要是通过滑动的平均速度来判断的,如果用户滑动速度超过设定速度,则验证失败。 所以我们需要使用到时间戳。 第一步,我们在移动事件一开始,获取到当前的时间戳;在移动事件结束将当前时间戳赋值给上一个时间,这样通过当前时间戳 -上一个时间就能获取到时间间隔。 第二步,我们还需要获取到偏移量,上面滑动原理已经介绍了如何获取。 第三步,有了时间间隔和偏移量,我们可以计算出本次滑动的速度,再利用总的滑动次数来获取到平均速度。 最后,我们只需要在touchend事件中做判断,判断滑块是否到达滑动的最大距离,并且滑块滑动的平均速度是否符合限制。 touchmove (e) { const offsetX = e.touches[0].localX - this.startPositionX const currTime = Date.now() if (this.startTime !== 0) { const duration = currTime - this.startTime // 传入倒数第二个点和最后一个点,和持续时间,会返回加速度 const v = parseInt(offsetX / duration) this.num++ this.s = this.s + v } this.startTime = currTime // 如果验证成功后仍允许滑动,则执行下面代码块(初始值默认为允许) if (this.isSlide) { //当x坐标大于最大可移动距离,那么当前x坐标即为最大可移动距离 if (offsetX >= this.max) { this.x = this.max } else { // 将当前鼠标x坐标给滑块移动的距离 this.x = offsetX; } } }, //松开滑块执行的事件 touchend (e) {// 计算平均速度 const avg = this.s / this.num console.log(avg) //自定义组件触发事件时提供的data对象 var data = {}; //如果触摸的X轴坐标大于等于限定的可移动范围,并且滑动的平均速度不能超过100,则验证成功 if (this.x == this.max && avg < this.limit) { //设置验证成功提示语 this.status = '验证成功'; //设置data对象的返回值 data.msg = true; //验证成功后,禁止滑块滑动 this.isSlide = false; } else { //元素X轴坐标归0 this.x = 0; //清空验证成功提示语 this.status = ''; this.tip = '验证失败' //设置data对象的返回值 data.msg = false; } this.$emit('getMsg', data) }
- index.js: // @ts-nocheckexport default{ data:{ tip: '右滑验证', x: 0,//X轴的初始值 startPositionX: 0,//触摸时X轴的值 max: 0,//滑块可移动的X轴范围 status: '',//验证完后的提示信息 isSlide: true,//是否允许验证成功后继续滑动 positionList: {}, // 存储坐标位置 startTime: 0, num: 0, // 总次数 s: 0 // 速度之和 }, props: { limit: { type: Number, default: 4 }, width: { type: Number, default: 400 }, height: { type: Number, default: 100 } }, onLayoutReady(){ let ball = this.$element("ball") let box = this.$refs.container // 滑块可以移动的最大距离 this.max = box.getBoundingClientRect().width - ball.getBoundingClientRect().width }, touchstart (e) { //设置X轴的始点 this.startPositionX = e.touches[0].localX; this.startTime = 0 this.s = 0 this.num = 0 }, //滑块移动中执行的事件 touchmove (e) { const offsetX = e.touches[0].localX - this.startPositionX const currTime = Date.now() if (this.startTime !== 0) { const duration = currTime - this.startTime // 传入倒数第二个点和最后一个点,和持续时间,会返回加速度 const v = parseInt(offsetX / duration) this.num++ this.s = this.s + v } this.startTime = currTime // 如果验证成功后仍允许滑动,则执行下面代码块(初始值默认为允许) if (this.isSlide) { //当x坐标大于最大可移动距离,那么当前x坐标即为最大可移动距离 if (offsetX >= this.max) { this.x = this.max } else { // 将当前鼠标x坐标给滑块移动的距离 this.x = offsetX; } } }, //松开滑块执行的事件 touchend (e) {// 计算平均速度 const avg = this.s / this.num //自定义组件触发事件时提供的data对象 var msg = {}; //如果触摸的X轴坐标大于等于限定的可移动范围,并且滑动的平均速度不能超过100,则验证成功 if (this.x == this.max && avg < this.limit) { //设置验证成功提示语 this.status = '验证成功'; //设置data对象的返回值 msg = true; //验证成功后,禁止滑块滑动 this.isSlide = false; } else { //元素X轴坐标归0 this.x = 0; //清空验证成功提示语 this.status = ''; this.tip = '验证失败' //设置data对象的返回值 msg = false; } this.$emit('getMsg', msg) }}
- 不足点:验证条件比较简单。 文章相关附件可以点击下面的原文链接前往下载: https://ost.51cto.com/resource/2234。 想了解更多关于开源的内容,请访问: 51CTO 开源基础软件社区 https://ost.51cto.com。

日常我们经常能见到验证码,网站上的验证码的作用是保护网站安全,一般网站都要通过验证码来防止机器大规模注册等危害。一般验证码有:图像验证、算数验证、滑动验证等。有些验证码验证起来有些麻烦,对我来说,最方便的验证方式是滑动滑块验证,滑块验证的使用体验非常好。
所以本篇文章我来尝试着实现一个滑动验证码。当然,这种验证码一般都是第三方来处理的,因为它不仅仅只是滑动,还会判断用户的拖放轨迹是否符合真实用户的行为特征,所以我只是简单的实现。
这是一个滑块验证码,用户只需要将滑块滑到最右侧,即可判断用户是否验证成功。
我为滑块验证添加了验证条件,用户可以对滑块速度做限制,例如:滑块滑倒右侧时,平均速度小于3,如果用户滑动速度大于3时,就验证失败。

我一共滑动了三次:
- 第一次:没有滑倒最右侧,认证失败。
- 第二次:滑动的速度太块,认证失败。
- 第三次:滑动速度符合限制,认证成功。
|
参数名称 |
参数描述 |
参数类型 |
默认值 |
|
width |
滑块宽度 |
Number |
300 |
|
height |
滑块高度 |
Number |
50 |
|
limit |
滑块的速率限制 |
Number |
4 |
|
事件名称 |
事件描述 |
|
getMsg |
验证通过或不通过事件 |
用户可以设置限制体速率,可以通过自定义事件getMsg,获取到验证的结果。

首先,我们需要在组件加载完成时,获取到滑块可以滑动的最大距离,我们用得到的最大距离,来判断滑块是否滑倒最右侧
注意组件的生命周期,在自定义组件中,是没有onShow的,需要用onLayoutReady(),这个钩子函数是自定义组件布局完成调用的。
然后,在触摸屏幕事件中,获取触摸的X坐标,此坐标为起始点;在触摸移动事件中,获取最新的X坐标,再减去起始坐标,就能得到偏移量。
最后,判断偏移量是否大于滑块可以滑动的最大距离,如果不大于,将偏移量设置为滑块的滑动距离。
为了更好理解,我把滑块隐藏部分显示出来。

touchstart (e) {
//设置X轴的始点
this.startPositionX = e.touches[0].localX;
this.startTime = 0
this.s = 0
this.num = 0
},
//滑块移动中执行的事件
touchmove (e) {
const offsetX = e.touches[0].localX - this.startPositionX
// 如果验证成功后仍允许滑动,则执行下面代码块(初始值默认为允许)
if (this.isSlide) {
//当x坐标大于最大可移动距离,那么当前x坐标即为最大可移动距离
if (offsetX >= this.max) {
this.x = this.max
} else {
// 将当前鼠标x坐标给滑块移动的距离
this.x = offsetX;
}
}
},
这里的验证不严谨,只是一个小尝试。
这里的验证不严谨,只是一个小尝试。
验证原理主要是通过滑动的平均速度来判断的,如果用户滑动速度超过设定速度,则验证失败。
所以我们需要使用到时间戳。
第一步,我们在移动事件一开始,获取到当前的时间戳;在移动事件结束将当前时间戳赋值给上一个时间,这样通过当前时间戳 -上一个时间就能获取到时间间隔。
第二步,我们还需要获取到偏移量,上面滑动原理已经介绍了如何获取。
第三步,有了时间间隔和偏移量,我们可以计算出本次滑动的速度,再利用总的滑动次数来获取到平均速度。
最后,我们只需要在touchend事件中做判断,判断滑块是否到达滑动的最大距离,并且滑块滑动的平均速度是否符合限制。
touchmove (e) {
const offsetX = e.touches[0].localX - this.startPositionX
const currTime = Date.now()
if (this.startTime !== 0) {
const duration = currTime - this.startTime
// 传入倒数第二个点和最后一个点,和持续时间,会返回加速度
const v = parseInt(offsetX / duration)
this.num++
this.s = this.s + v
}
this.startTime = currTime
// 如果验证成功后仍允许滑动,则执行下面代码块(初始值默认为允许)
if (this.isSlide) {
//当x坐标大于最大可移动距离,那么当前x坐标即为最大可移动距离
if (offsetX >= this.max) {
this.x = this.max
} else {
// 将当前鼠标x坐标给滑块移动的距离
this.x = offsetX;
}
}
},
//松开滑块执行的事件
touchend (e) {
// 计算平均速度
const avg = this.s / this.num
console.log(avg)
//自定义组件触发事件时提供的data对象
var data = {};
//如果触摸的X轴坐标大于等于限定的可移动范围,并且滑动的平均速度不能超过100,则验证成功
if (this.x == this.max && avg < this.limit) {
//设置验证成功提示语
this.status = '验证成功';
//设置data对象的返回值
data.msg = true;
//验证成功后,禁止滑块滑动
this.isSlide = false;
} else {
//元素X轴坐标归0
this.x = 0;
//清空验证成功提示语
this.status = '';
this.tip = '验证失败'
//设置data对象的返回值
data.msg = false;
}
this.$emit('getMsg', data)
}
index.js:
// @ts-nocheck
export default{
data:{
tip: '右滑验证',
x: 0,//X轴的初始值
startPositionX: 0,//触摸时X轴的值
max: 0,//滑块可移动的X轴范围
status: '',//验证完后的提示信息
isSlide: true,//是否允许验证成功后继续滑动
positionList: {}, // 存储坐标位置
startTime: 0,
num: 0, // 总次数
s: 0 // 速度之和
},
props: {
limit: {
type: Number,
default: 4
},
width: {
type: Number,
default: 400
},
height: {
type: Number,
default: 100
}
},
onLayoutReady(){
let ball = this.$element("ball")
let box = this.$refs.container
// 滑块可以移动的最大距离
this.max = box.getBoundingClientRect().width - ball.getBoundingClientRect().width
},
touchstart (e) {
//设置X轴的始点
this.startPositionX = e.touches[0].localX;
this.startTime = 0
this.s = 0
this.num = 0
},
//滑块移动中执行的事件
touchmove (e) {
const offsetX = e.touches[0].localX - this.startPositionX
const currTime = Date.now()
if (this.startTime !== 0) {
const duration = currTime - this.startTime
// 传入倒数第二个点和最后一个点,和持续时间,会返回加速度
const v = parseInt(offsetX / duration)
this.num++
this.s = this.s + v
}
this.startTime = currTime
// 如果验证成功后仍允许滑动,则执行下面代码块(初始值默认为允许)
if (this.isSlide) {
//当x坐标大于最大可移动距离,那么当前x坐标即为最大可移动距离
if (offsetX >= this.max) {
this.x = this.max
} else {
// 将当前鼠标x坐标给滑块移动的距离
this.x = offsetX;
}
}
},
//松开滑块执行的事件
touchend (e) {
// 计算平均速度
const avg = this.s / this.num
//自定义组件触发事件时提供的data对象
var msg = {};
//如果触摸的X轴坐标大于等于限定的可移动范围,并且滑动的平均速度不能超过100,则验证成功
if (this.x == this.max && avg < this.limit) {
//设置验证成功提示语
this.status = '验证成功';
//设置data对象的返回值
msg = true;
//验证成功后,禁止滑块滑动
this.isSlide = false;
} else {
//元素X轴坐标归0
this.x = 0;
//清空验证成功提示语
this.status = '';
this.tip = '验证失败'
//设置data对象的返回值
msg = false;
}
this.$emit('getMsg', msg)
}
}
不足点:验证条件比较简单。
文章相关附件可以点击下面的原文链接前往下载:
https://ost.51cto.com/resource/2234。