基于JS实现发送验证码的计时器效果

 更新时间:2023年11月30日 11:21:00   作者:Ashy  
这篇文章主要为大家详细介绍了如何基于JS实现一个发送验证码的计时器效果,文中的示例代码讲解详细,感兴趣的小伙伴快跟随小编一起学习一下吧

一、实现效果

需求:

  • 点击按钮后开始读秒
  • 读秒期间不可点击
  • 读秒结束后可以继续点击

二、实现思路(步骤)

1.要做到计时器的效果,首先得实现一个读秒的效果

let count = 60; // 这里只做演示说明 Gif 中是 10
setInterval(() => {
  count = count - 1
}, 1000)

2.清除定时器的效果,处理状态

let count = 10;
let timer = setInterval(() => {
  count = count - 1
}, 1000)

// 这里我用 setTimeout 来做 clearInterval 的操作
setTimeout(function () {
  timer && clearInterval(timer)
  // 清理定时器的时机为 10 次之后
}, 10 * 1000)

注:

这里对于 setTimeout 清理 setInterval 这个定时器做一个说明

原本我的实现是在 setInterval 的执行中通过判断计数来销毁这个定时器的,但是发现定时器依然在执行,执行的原因是:setInterval 函数会在执行完回调函数后,创建一个新的定时器,并将旧的定时器销毁。 因此,当你在 setInterval 中执行 clearInterval 时,实际上是清除了一个已经被销毁的定时器。

通过以上两步,就可以实现了需求 1。将上述操作封装函数就可以得到一个简单的定时器功能了。

3.处理定时器的读秒期间不可点击实现(需求 2)

/**
 * @param {number} initCount 调用次数
 * @param {(count: number) => count} time 定时器执行时间间隔
 * @returns [开始调用, 计数器, 是否执行中]
 */
let tiggering = false;
export const tigger = (initCount = 60, callback: (count: number) => count) => {
    let count = initCount;
    let timer: NodeJS.Timeout | null = null
    
    // 如果未触发,则可以执行定时器
    if (!tiggering) {
        tiggering = true
        timer = setInterval(() => {
            count = count - 1
            // 定时器每次执行后更新回调,这样可以在页面使用该状态
            callback(count)
        }, time)
    }

    setTimeout(function () {
        // 定时器结束时设置更新触发状态
        tiggering = false
        timer && clearInterval(timer)
    }, count * time)
}

在这里我是将逻辑部分抽离为工具函数的使用,在实际项目中有步骤 2,在合适的时机做相对应的逻辑处理,基本够用了。

这段代码的实现基本没什么大的问题了,tiggering 状态的维护是放在了工具函数之外,感觉不是很优雅。在函数内部的实现话就需要用到闭包维护内部函数的形式来保护这个变量了,这点大家可以看看表达下自己的想法~

三、封装一个适用的 React 自定义 hook

实现思路大致和 步骤 3 类似:

import { useState } from 'react'

/**
 * @param initCount 调用次数
 * @param time 定时器执行时间间隔,这里支持修改真实的时间间隔
 * @returns [开始调用, 计数器, 是否执行中]
 */
export default (initCount = 120, time = 1000): [() => void, number, boolean] => {
  // 维护调用次数
  const [count, setCount] = useState(initCount)
  // 维护触发状态,用于 UI 部分实现禁用
  const [tiggering, setTiggering] = useState(false)

  let timer: NodeJS.Timeout | null = null
  const tigger = () => {
    // 注:在这里又进行了一次 setCount 赋值操作,是为了解决第一次验证码读秒结束后,
    // 第二次验证码执行(tigger 函数调用)时,自定义 hook 已经执行,count 的值为 0 的情况
    setCount(initCount)
    if (!tiggering) {
      setTiggering(true)
      timer = setInterval(() => {
        setCount(count => count - 1)
      }, time)
    }

    setTimeout(function () {
      timer && clearInterval(timer)
      setTiggering(false)
    }, initCount * time)
  }

  return [tigger, count, tiggering]
}

组件中使用

这里简写实现过程

// ... 引入略
const [tigger, count, tiggering] = useTimeCount(10)

const sendCode = () => {
    // 发送验证吗
    getMailCode({ receiver: code }).then(res => {
        if (res) {
            tigger()
            // 这里可以执行其他逻辑,如发送成功的提示
        }
    })
}

return (
    <Button disabled={tiggering} className='send-btn' onClick={sendCode}>
        {tiggering ? `${count}s` : 'Send code'}
    </Button>
)

小结

在实现这套流程的时候,一开始觉得是个简单的实现,在实现过程中还是踩了一些小坑的,比如上文中说到的 clearInterval 的销毁时机的问题;以及考虑了下普通函数封装(步骤 3)。

到此这篇关于基于JS实现发送验证码的计时器效果的文章就介绍到这了,更多相关JS计时器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • JavaScript检查一个值是否为数字实例代码

    JavaScript检查一个值是否为数字实例代码

    众所周知在JavaScript编程中判断输入是否为数字类型是一个常见的需求,特别是在处理用户输入或者验证表单数据时,这篇文章主要介绍了JavaScript检查一个值是否为数字的相关资料,需要的朋友可以参考下
    2025-11-11
  • JavaScript高级程序设计阅读笔记(六) ECMAScript中的运算符(二)

    JavaScript高级程序设计阅读笔记(六) ECMAScript中的运算符(二)

    ECMAScript中的运算符,学习js的朋友可以参考下
    2012-02-02
  • JavaScript Uploadify文件上传实例

    JavaScript Uploadify文件上传实例

    这篇文章主要为大家详细介绍了Uploadify文件上传小实例,一个简单的jsp上传小功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-02-02
  • JavaScript计算两个日期之间天数的各种方法总结

    JavaScript计算两个日期之间天数的各种方法总结

    这篇文章主要介绍了利用JavaScript计算两个日期之间天数的各种方法,你可以使用JavaScript的Date对象来计算两个字符串日期之间的天数差异,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2025-07-07
  • 使用JS正则表达式 替换括号,尖括号等

    使用JS正则表达式 替换括号,尖括号等

    下面小编就为大家带来一篇使用JS正则表达式 替换括号,尖括号等。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-11-11
  • 在纯TypeScript项目中使用Alias Path问题

    在纯TypeScript项目中使用Alias Path问题

    本文介绍了在大型TypeScript项目中使用别名路径简化模块导入路径的方法,主要步骤包括修改tsconfig.json配置别名路径、确保构建工具支持别名路径,并在项目中使用别名路径,这有助于提高代码的可读性和可维护性
    2026-04-04
  • JavaScript实现九宫格点击变色效果

    JavaScript实现九宫格点击变色效果

    这篇文章主要为大家详细介绍了JavaScript实现九宫格点击变色效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-08-08
  • js前端实现图片压缩上传的示例代码

    js前端实现图片压缩上传的示例代码

    这篇文章主要为大家详细介绍了js前端如何实现图片压缩上传的效果,文中的示例代码讲解详细,具有一定的学习价值,有需要的小伙伴可以参考一下
    2023-11-11
  • JS实现跟随鼠标闪烁转动色块的方法

    JS实现跟随鼠标闪烁转动色块的方法

    这篇文章主要介绍了JS实现跟随鼠标闪烁转动色块的方法,涉及javascript操作html元素及css样式的技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-02-02
  • js canvas实现简单的图像扩散效果

    js canvas实现简单的图像扩散效果

    这篇文章主要为大家详细介绍了js canvas实现简单的图像扩散效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-09-09

最新评论