广告位联系
返回顶部
分享到

使用H5实现短信验证码一键登录功能

html5 来源:互联网 作者:佚名 发布时间:2023-09-20 23:37:46 人浏览
摘要

一、技术栈 uniapp+vue3+javascript 二、实现的效果 全部代码可见:https://github.com/zzm319/study-summarize.git(分支为code-login)。 1、进入页面第一个输入框自动聚焦 2、输入后下一个输入框自动聚

一、技术栈

uniapp+vue3+javascript

二、实现的效果

全部代码可见:https://github.com/zzm319/study-summarize.git(分支为code-login)。

1、进入页面第一个输入框自动聚焦

2、输入后下一个输入框自动聚焦

3、点击输入区域自动聚焦到无值的第一个输入框(当前一个输入框无值时后一个输入框无法聚焦 )

4、可以复制粘贴填充也可以短信验证码一键登录

5、监听键盘的删除键(Backspace)删除输入的验证码

三、实现逻辑及代码

1、HTML部分:

利用循环渲染4个输入框,第一个输入框可输入最大长度无值时为4(为了复制和验证码填充赋值),有值时最大可输入长度为1。

1

2

3

4

5

6

7

8

9

10

11

<template>

    <view class="content">

        <view class="code-area">

            <view class="propmt">已发送4位验证码至 +86 {{ phoneNum }}</view>

            <view class="code-input" @click="handleFocus">

                <input v-for="(item, index) in inputbox" type="number" :key="index" v-model="item.labelValue"

                    class="input-code" :maxlength="index === 0 && isMaxLength ? 4 : 1" @input="onInput($event, index)" />

            </view>

        </view>

    </view>

</template>

2、javascript部分:

1)进入页面第一个输入框自动聚焦:

1

2

3

4

5

6

onMounted(() => {

    // #ifdef H5

    // 处理聚焦第一个输入框

    document.querySelectorAll('.uni-input-input')[0].focus();

    // #endif

})

2. 输入后下一个输入框自动聚焦,主要是给输入框监听输入事件,判断是否有值,有值就自动聚焦下一个输入框:

1

2

3

4

5

6

7

8

9

// 监听输入输入框 自动聚焦到下一个输入框

const onInput = (e, index) => {

    // index < 3 ,如果是第4格,不触发光标移动至下一个输入框。

    if (inputbox[index].labelValue && index < 3) {

        nextTick(() => {

            document.querySelectorAll('.uni-input-input')[index + 1].focus()

        })

    }

}

3)点击输入区域自动聚焦到无值的第一个输入框(当前一个输入框无值时后一个输入框无法聚焦 ),主要是给输入框区域判定一个点击事件,判断当前哪个输入框无值则聚焦:

1

2

3

4

5

6

7

8

// 点击输入区域 自动聚焦到空的输入框

const handleFocus = () => {

    if (focusIndex.value === 4) {

        document.querySelectorAll('.uni-input-input')[3].focus();

        return;

    }

    document.querySelectorAll('.uni-input-input')[focusIndex.value].focus();

}

4)监听粘贴事件赋值给每个输入框,主要是利用给第一个输入框赋值后,然后给剩下的三个输入框重新赋值(短信验证码填充同理):

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

// 监听输入区域的粘贴事件

    document.querySelector('.code-input').addEventListener('paste', (event) => {

        const pasteText = (event.clipboardData || window.clipboardData).getData("text");

        const arr = pasteText.split('').filter(item => /\d/.test(Number(item)));

        const newArr = arr.slice(0, 4).map(item => Number(item));

        if (newArr.length) {

            inputbox[0].labelValue = newArr.join('');

        }

    })

// 监听第一个输入框的值:为了处理粘贴和短信自动填充时赋值和聚焦

watch(() => inputbox[0].labelValue, (val) => {

    if (val) {

        // 处理输入的时候限制输入长度

        isMaxLength.value = false;

    }

    nextTick(() => {

        if (val && val.length >= 2) {

            val.split('').forEach((element, index) => {

                inputbox[index].labelValue = element;

            });

        }

?

        setTimeout(() => {

            // 加个定时器 避免粘贴两次

            handleFocus();

        })

    })

})

注意的是,二次粘贴时需要先重置第一个输入框的最大可输入长度:

1

2

3

4

5

6

7

8

9

10

11

watch(() => inputCodeValue.value, async (val) => {

    if (!val) {

        // 处理四位输入框为空时再次复制粘贴

        isMaxLength.value = true;

    }

?

    if (val.length === 4) {

        // 四位输入框的值已填满 做登录等逻辑操作

        console.log('to login')

    }

})

5)监听键盘的删除键(Backspace)删除输入的验证码:

1

2

3

4

5

6

7

8

9

10

11

// 监听键盘上的删除按键(Backspace)

const handleListenDelete = (e) => {

    if (e.keyCode === 8 && focusIndex.value > 0) {

        inputbox[focusIndex.value - 1].labelValue = '';

        document.querySelectorAll('.uni-input-input')[focusIndex.value].focus();

    }

}

?

onMounted(() => {

document.addEventListener('keydown', handleListenDelete)

})

3、完整javascript代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

<script setup>

import { ref, reactive, watch, onBeforeUnmount, nextTick, onMounted, computed } from 'vue';

?

let inputbox = reactive(new Array(4).fill().map((item, index) => ({ id: index, labelValue: '' })));

let phoneNum = ref('');

let isMaxLength = ref(true);

?

// 四位短信验证码

const inputCodeValue = computed(() => inputbox.reduce((pre, item) => pre + item.labelValue, ''))

?

// 验证码的长度

const focusIndex = computed(() => inputCodeValue.value.length)

?

// 监听键盘上的删除按键(Backspace)

const handleListenDelete = (e) => {

    if (e.keyCode === 8 && focusIndex.value > 0) {

        inputbox[focusIndex.value - 1].labelValue = '';

        document.querySelectorAll('.uni-input-input')[focusIndex.value].focus();

    }

}

?

?

onMounted(() => {

    // #ifdef H5

    // 处理聚焦第一个输入框

    document.querySelectorAll('.uni-input-input')[0].focus()

?

    document.addEventListener('keydown', handleListenDelete)

?

    // 监听输入区域的粘贴事件

    document.querySelector('.code-input').addEventListener('paste', (event) => {

        const pasteText = (event.clipboardData || window.clipboardData).getData("text");

        const arr = pasteText.split('').filter(item => /\d/.test(Number(item)));

        const newArr = arr.slice(0, 4).map(item => Number(item));

        if (newArr.length) {

            inputbox[0].labelValue = newArr.join('');

        }

    })

    // #endif

})

?

// 监听第一个输入框的值:为了处理粘贴和短信自动填充时赋值和聚焦

watch(() => inputbox[0].labelValue, (val) => {

    if (val) {

        // 处理输入的时候限制输入长度

        isMaxLength.value = false;

    }

    nextTick(() => {

        if (val && val.length >= 2) {

            val.split('').forEach((element, index) => {

                inputbox[index].labelValue = element;

            });

        }

?

        setTimeout(() => {

            // 加个定时器 避免粘贴两次

            handleFocus();

        })

    })

})

?

watch(() => inputCodeValue.value, async (val) => {

    if (!val) {

        // 处理四位输入框为空时再次复制粘贴

        isMaxLength.value = true;

    }

?

    if (val.length === 4) {

        // 四位输入框的值已填满 做登录等逻辑操作

        console.log('to login')

    }

})

?

// 点击输入区域 自动聚焦到空的输入框

const handleFocus = () => {

    if (focusIndex.value === 4) {

        document.querySelectorAll('.uni-input-input')[3].focus();

        return;

    }

    document.querySelectorAll('.uni-input-input')[focusIndex.value].focus();

}

?

// 监听输入输入框 自动聚焦到下一个输入框

const onInput = (e, index) => {

    // index < 3 ,如果是第4格,不触发光标移动至下一个输入框。

    if (inputbox[index].labelValue && index < 3) {

        nextTick(() => {

            document.querySelectorAll('.uni-input-input')[index + 1].focus()

        })

    }

}

?

?

onBeforeUnmount(() => {

    document.removeEventListener('keydown', handleListenDelete);

})

?

</script>

四、遇到的问题

1、聚焦实现

由于uniapp使用input是通过封装原生input标签实现的,使用ref获取input dom节点的方式,不能调用focus方法实现聚焦,所以采用原生的获取dom方法实现:

1

document.querySelectorAll('.uni-input-input')[focusIndex.value].focus();

2、循环渲染input的方法,当某个输入框的值改变其它输入框也跟着改变 原因是我fill()了一个对象,这种方式相当于四个输入框的值都是同一个对象。

1

let inputbox = reactive(new Array(4).fill({ id: index, labelValue: '' });

3、在做点击输入区域,让焦点自动聚焦到无值的第一个输入框时,发现点击输入框不能实现,点击输入框之间的间隔可以实现。 原因:我给每个输入框设置了diabled属性,让其在上一个输入框有值时才能使用。

1

:disabled="item.labelValue || (index >= 1 && !inputbox[index - 1].labelValue)"

4、ios的safari浏览器中,验证码填充背景颜色会为黄色: (ps:网上有很多种方法:改变背景色,改变阴影填充等,本人试了都不能实现,下面的方法在iphone14 ios版本为16.1.1中亲测有效)

1

2

3

4

5

// 处理去掉safari浏览器填充短信验证码背景色

/deep/ .uni-input-input {

            -webkit-text-fill-color: #262C33;

            transition: background-color 5000s ease-out 0.5s;

        }


版权声明 : 本文内容来源于互联网或用户自行发布贡献,该文观点仅代表原作者本人。本站仅提供信息存储空间服务和不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权, 违法违规的内容, 请发送邮件至2530232025#qq.cn(#换@)举报,一经查实,本站将立刻删除。
原文链接 :
相关文章
  • HTML5实现同时选择多个文件夹上传的使用介绍
    HTML5的上传API可以支持同时选择多个文件和选择单个文件夹,但不支持同时选择多个文件夹。如果想同时选择多个文件夹,那只能另辟蹊径,
  • 使用H5实现短信验证码一键登录功能

    使用H5实现短信验证码一键登录功能
    一、技术栈 uniapp+vue3+javascript 二、实现的效果 全部代码可见:https://github.com/zzm319/study-summarize.git(分支为code-login)。 1、进入页面第一个输
  • H5使用Vant自适应布局(postcss-pxtorem)介绍
    1、安装 postcss-pxtorem 1 npm install postcss postcss-pxtorem --save-dev 2、在根目录新建postcss.config.js,配置 postcss-pxtorem 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1
  • html中ul和li标签的用法介绍

    html中ul和li标签的用法介绍
    普通的显示数据的时候,ul就是项目列表,li就是列表项。可以用来显示数据。如果用于DIV+CSS布局的话,ul+li可以替换表格的作用,具体的
  • HTML5 Web Worker(多线程处理)介绍

    HTML5 Web Worker(多线程处理)介绍
    概述 JavaScript的执行环境是单线程的,也就是一次只能执行一个任务。如果遇到多个任务时,只能排队依次执行。 在HTML5中,可以使用Web W
  • html5播放器实现倍速播放的方法介绍
    定义和用法 playbackRate 属性设置或返回音频的当前播放速度。 playbackspeed 指示音频的当前播放速度。 例值: 1.0 正常速度 0.5 半速(更慢)
  • 短视频滑动播放在H5下的实现方式

    短视频滑动播放在H5下的实现方式
    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 短视频已经无数不在了,但是主体还是使用 app 来承载的。本文讲述
  • HTML5页面打开微信小程序功能实现

    HTML5页面打开微信小程序功能实现
    微信终于支持由页面跳转至小程序啦 ~ 步骤一:绑定域名 登录微信公众平台进入公众号设置的功能设置里填写JS接口安全域名。 步骤二:引
  • html5+实现plus.io进行拍照和图片等获取
    使用Hbuilder开发工具开发:实现可对Android机进行控制和获取资源 说明:IO模块管理本地文件系统,用于对文件系统的目录浏览、文件的读取
  • HTML标签实现带动画的抖音LOGO效果

    HTML标签实现带动画的抖音LOGO效果
    先上结果,最终实现效果如下: 还原度应该还可以吧? 抖音Logo结构 想要用CSS来画抖音的Logo,前提要先了解它的构造,一定是一些几何图形
  • 本站所有内容来源于互联网或用户自行发布,本站仅提供信息存储空间服务,不拥有版权,不承担法律责任。如有侵犯您的权益,请您联系站长处理!
  • Copyright © 2017-2022 F11.CN All Rights Reserved. F11站长开发者网 版权所有 | 苏ICP备2022031554号-1 | 51LA统计