4

HarmonyOS 实现一个滑块验证-51CTO.COM

 1 year ago
source link: https://os.51cto.com/article/715446.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

HarmonyOS 实现一个滑块验证-51CTO.COM

HarmonyOS 实现一个滑块验证
作者:lxj29 2022-08-02 14:21:20
本篇文章我来尝试着实现一个滑动验证码。当然,这种验证码一般都是第三方来处理的,因为它不仅仅只是滑动,还会判断用户的拖放轨迹是否符合真实用户的行为特征,所以我只是简单的实现。
f405112168c371d1f9c0086cf183e676d85fb6.png

​想了解更多关于开源的内容,请访问:​

​51CTO 开源基础软件社区​

​https://ost.51cto.com​

日常我们经常能见到验证码,网站上的验证码的作用是保护网站安全,一般网站都要通过验证码来防止机器大规模注册等危害。一般验证码有:图像验证、算数验证、滑动验证等。有些验证码验证起来有些麻烦,对我来说,最方便的验证方式是滑动滑块验证,滑块验证的使用体验非常好。

所以本篇文章我来尝试着实现一个滑动验证码。当然,这种验证码一般都是第三方来处理的,因为它不仅仅只是滑动,还会判断用户的拖放轨迹是否符合真实用户的行为特征,所以我只是简单的实现。

这是一个滑块验证码,用户只需要将滑块滑到最右侧,即可判断用户是否验证成功。

我为滑块验证添加了验证条件,用户可以对滑块速度做限制,例如:滑块滑倒右侧时,平均速度小于3,如果用户滑动速度大于3时,就验证失败。

#夏日挑战赛# HarmonyOS 实现一个滑块验证-开源基础软件社区

我一共滑动了三次:

  • 第一次:没有滑倒最右侧,认证失败。
  • 第二次:滑动的速度太块,认证失败。
  • 第三次:滑动速度符合限制,认证成功。

1、参数支持

width

Number

height

Number

limit

滑块的速率限制

Number

2、事件支持

getMsg

验证通过或不通过事件

用户可以设置限制体速率,可以通过自定义事件getMsg,获取到验证的结果。

#夏日挑战赛# HarmonyOS 实现一个滑块验证-开源基础软件社区

1、滑动原理

首先,我们需要在组件加载完成时,获取到滑块可以滑动的最大距离,我们用得到的最大距离,来判断滑块是否滑倒最右侧

注意组件的生命周期,在自定义组件中,是没有onShow的,需要用onLayoutReady(),这个钩子函数是自定义组件布局完成调用的。

然后,在触摸屏幕事件中,获取触摸的X坐标,此坐标为起始点;在触摸移动事件中,获取最新的X坐标,再减去起始坐标,就能得到偏移量。

最后,判断偏移量是否大于滑块可以滑动的最大距离,如果不大于,将偏移量设置为滑块的滑动距离。

为了更好理解,我把滑块隐藏部分显示出来。

#夏日挑战赛# HarmonyOS 实现一个滑块验证-开源基础软件社区
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;
                }
            }
    },

2、验证原理

这里的验证不严谨,只是一个小尝试。

验证原理主要是通过滑动的平均速度来判断的,如果用户滑动速度超过设定速度,则验证失败。

所以我们需要使用到时间戳。

第一步,我们在移动事件一开始,获取到当前的时间戳;在移动事件结束将当前时间戳赋值给上一个时间,这样通过当前时间戳 -上一个时间就能获取到时间间隔。

第二步,我们还需要获取到偏移量,上面滑动原理已经介绍了如何获取。

第三步,有了时间间隔和偏移量,我们可以计算出本次滑动的速度,再利用总的滑动次数来获取到平均速度。

最后,我们只需要在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。

​想了解更多关于开源的内容,请访问:​

​51CTO 开源基础软件社区​

​https://ost.51cto.com​​。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK