• 如何实现滑动验证码功能?
  • 发布于 2个月前
  • 213 热度
    0 评论
简述
在开始开发工作之前,我们有必要先了解一下相关Javascript函数,方便我们后续的开发工作
在PC端
我们经常使用鼠标相关的事件来进行交互。下面是一些常见的鼠标事件:
click:当用户点击鼠标左键时触发。
dblclick:当用户双击鼠标左键时触发。
mousedown:当用户按下鼠标按钮时触发。
mouseup:当用户释放鼠标按钮时触发。
mousemove:当用户移动鼠标时触发。
mouseover:当用户将鼠标移动到元素上方时触发。
mouseout:当用户将鼠标移出元素时触发。

这些事件可以通过JavaScript来进行处理。我们可以使用事件监听器将特定的事件与特定的元素关联起来,从而在事件触发时执行相应的操作。此外,在一些库和框架中,可能还会有更多的鼠标相关事件和功能可供使用。例如,一些图形库可能提供鼠标绘图功能,而一些游戏引擎可能提供鼠标控制功能,当然这些不是我写这篇文章所要说的,就简单的从鼠标滑动验证开始,凡事必先利其器,方能有效地使用鼠标事件来进行交互。


但是有时候,我们有些用户会通过移动端(如手机、ipad等)用手触控的方式去访问PC网站的时候,鼠标事件就不起作用。所以要考虑到一些兼容的情况,那么就有了下面关于移动端的内容。


在移动端
如触摸(touch)、滑动(swipe)、捏合(pinch) 等,是用来与移动设备进行互动的重要手段,而我主要总结下触摸相关,并且待会用于开发滑动验证组件的方法,如下:
常见的触摸相关事件包括以下几种:
touchstart:当手指触摸屏幕时触发,即手指接触到触摸表面。
touchmove:当手指在屏幕上移动时触发,即手指在触摸表面上滑动。
touchend:当手指从屏幕上离开时触发,即手指离开触摸表面。
touchcancel:在手指移动过程中,如果有其他事件(如电话呼入)发生,会触发该事件,取消当前触摸过程。
touchenter:当手指触摸到某个元素时触发,即手指进入元素所在区域。
touchleave:当手指从某个元素上离开时触发,即手指离开元素所在区域。

通过监听这些触摸事件,我们可以实现不同的交互效果和功能,比如通过滑动事件来实现轮播图、通过长按事件来实现弹出菜单,当然也可以来实现验证组件。同时,还可以通过事件对象获取触摸点的坐标信息,从而精确地处理触摸操作。好了,废话不多说,我们开始着眼于开发工作。


滑动验证组件
先上成型的滑动组件效果图
第一张命名为:

第二张命名为:

JYM看了这两张图后,可能觉得少了那么一些花里胡哨,看起来好像也蛮简单的。但是嘛,涉及到的知识点也不少。
我们先来梳理一下开发思路:
思路梳理
1.定义组件结构:确定滑动验证组件的整体结构,可以使用HTML和CSS来布局和样式化组件。一般包括一个容器用于显示滑块和背景,一个滑块用于拖动,以及一个按钮用于触发验证。
2.实现滑块拖动功能:通过监听触摸事件或鼠标事件,实现滑块的拖动功能。可以使用JavaScript来获取触摸或鼠标事件的坐标信息,并根据拖动距离来改变滑块的位置。
3.添加验证逻辑:当滑块被拖动到预定位置时,需要触发验证逻辑。可以定义一个阈值,当滑块的位置超过阈值时,认为验证成功。可以使用JavaScript来判断滑块位置是否超过阈值,并触发验证结果。
4.添加反馈效果:根据验证结果,可以添加相应的反馈效果,比如验证成功时显示成功提示,验证失败时显示失败提示。可以使用CSS动画或Class切换来实现反馈效果的显示与隐藏。
5.提供可配置选项:为了满足不同场景的需求,可以为组件提供一些可配置的选项,例如滑块的占比、滑块背景的颜色、验证成功提示的内容等。
添加事件回调:为了让开发者能够在验证成功或失败后执行相应的处理逻辑,可以为组件提供事件回调函数,例如验证成功回调和验证失败回调。

代码实现
第一步:定义组件结构
<div class="drag">
    <div class="bg" />
    <div class="text" @selectstart="sotp">
            <img v-if="success" src="@/assets/icon/login_icon_successful.png" width="16px" />
            {{ tips }}
    </div>
    <div class="btn" />
</div>
并用CSS来布局和样式化
const oDarg = getDom('.drag');
const oBg = getDom('.bg');
const oText = getDom('.text');
const oBtn = getDom('.btn');
oBtn.style.left = 0;
oBg.style.width = 0;
oBg.style.transition = 'width 1s ease';
oBtn.style.transition = 'left 1s ease';
tips.value = '滑动验证';
success.value = false;
oText.style.color = '#666666';
oText.style.background = '#E5E5E5';
第二步:实现滑块拖动功能
通过监听触摸事件或鼠标事件,实现滑块的拖动功能,如下:
//堆代码 duidaima.com
// PC端事件
// 鼠标按下事件
oBtn.onmousedown = function (eve) {
    console.log('叮咚');
    // const phone = _this.form.getFieldValue('phone')
    // const password = _this.form.getFieldValue('password')
    // if (!phone || !password) {
    //   _this.$message.info(_this.$t('msg.telPsw'))
    //   return false
    // }
    // this.isMouseUp = false

    oText.style.background = 'none';
    oBg.style.transition = '';
    oBtn.style.transition = '';
    const e = eve || window.event;
    const downX = e.clientX;
    // eslint-disable-next-line no-unused-vars
    let successPan = false; // 判断验证是否成功
    const distance = oDarg.offsetWidth - oBtn.offsetWidth; // 验证成功的距离
    // 鼠标移动
    document.onmousemove = function (eve) {
            console.log('onmousemove');
            const e = eve || window.event;
            const moveX = e.clientX;
            let offsetX = moveX - downX;
            if (offsetX > distance) {
                    offsetX = distance;
            } else if (offsetX < 0) {
                    offsetX = 0;
            }
            oBtn.style.left = `${offsetX}px`;
            oBg.style.width = `${offsetX}px`;
            if (offsetX === distance) {
                    // 判断验证通过
                    // _this.tips = _this.$t('login.verificationRes')
                    tips.value = '验证成功';
                    success.value = true;
                    // oBtn.innerHTML = '&radic;'
                    oText.style.color = '#FFF';
                    oBtn.style.color = '#4CAF50';
                    successPan = true; // 验证通过时的条件
                    siliding.value = successPan;
                    console.log(siliding, 'this.siliding');
                    document.onmousemove = null; // 验证通过后 鼠标按下事件和鼠标移动都没用了 因此需要清除
                    oBtn.onmousedown = null;
            }
    };
    // 鼠标抬起事件
    document.onmouseup = function () {
        if (!successPan) {
                oBtn.style.left = 0;
                oBg.style.width = 0;
                oBg.style.transition = 'width 1s ease';
                oBtn.style.transition = 'left 1s ease';
        }
        document.onmousemove = null;
        oBtn.onmouseup = null;
    };
};
其中,onmousemove和onmouseup这两个方法,已经在简述中,提过了它的触发条件,当然也得考虑到移动端访问的情况,
// 移动端事件

oBtn.ontouchstart = function (eve) {
    console.log('ontouchstart');
    // const phone = _this.form.getFieldValue('phone')
    // const password = _this.form.getFieldValue('password')
    // if (!phone || !password) {
    //   _this.$message.info(_this.$t('msg.telPsw'))
    //   return false
    // }
    this.isMouseUp = false;
    oText.style.background = 'none';
    oBg.style.transition = '';
    oBtn.style.transition = '';
    let e = eve || window.event;
    // 移动端特殊处理
    e = 'ontouchstart' in document ? e.touches[0] : e;
    const downX = e.clientX;
    // eslint-disable-next-line no-unused-vars
    let successPan = false; // 判断验证是否成功
    const distance = oDarg.offsetWidth - oBtn.offsetWidth; // 验证成功的距离
    // 鼠标移动
    // document => oBtn
    oBtn.ontouchmove = function (eve) {
        console.log('ontouchmove');
        console.log(eve);

        let e = eve || window.event;
        // 移动端特殊处理
        e = 'ontouchstart' in document ? e.touches[0] : e;
        console.log(e.clientX);

        const moveX = e.clientX;
        let offsetX = moveX - downX;
        if (offsetX > distance) {
                offsetX = distance;
        } else if (offsetX < 0) {
                offsetX = 0;
        }
        oBtn.style.left = `${offsetX}px`;
        oBg.style.width = `${offsetX}px`;
    if (offsetX === distance) {
            // 判断验证通过
            // _this.tips = _this.$t('login.verificationRes')
            // _this.success = true
            tips.value = '验证成功';
            success.value = true;

            // oBtn.innerHTML = '&radic;'
            oText.style.color = '#FFF';
            oBtn.style.color = '#4CAF50';
            successPan = true; // 验证通过时的条件
            siliding.value = successPan;
            console.log(siliding.value, 'this.siliding');
            // document => oBtn
            oBtn.ontouchmove = null; // 验证通过后 鼠标按下事件和鼠标移动都没用了 因此需要清除
            oBtn.ontouchstart = null;
    }
};
依此类推,在这里就不过的阐述
第三步:添加验证逻辑
当滑块被拖动到预定位置时,需要触发验证逻辑,并设定一个成功的阈值
const distance = oDarg.offsetWidth - oBtn.offsetWidth; // 验证成功的距离
我这里设置的阈值是,轨道总长度 - 按钮总长度。
当用户滑动按钮到达distance范围时,只要是小于或等于,都算滑动验证成功,并自动完成剩余的滑动轨迹

第四步:添加反馈效果
给与相应的提示和颜色加持

第五步:提供可配置选项
等我健身回来再补充,并发布代码,如果感兴趣,请先加入收藏,顺便给个小拇指谢谢!

用户评论