在现代 Web 应用中,手机号验证和验证码发送是常见的功能需求。本文将结合一个完整的示例,详细解析如何使用 JavaScript 实现这一功能,并深入探讨其中涉及的关键知识点。
目录
一、基本功能概述以及完整代码
我们要实现的功能是:用户输入手机号,点击"发送验证码"按钮后,系统验证手机号格式是否正确。如果正确,按钮将变为不可用状态并显示倒计时,防止用户重复点击;如果格式错误,则显示相应的提示信息。
完整的实现代码:
```html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>验证码</title>
</head>
<body>
<input type="text" id="inp" placeholder="请输入手机号" />
<button οnclick="fun()" id="but">发送验证码</button>
<span id="span"></span>
<script>
// 正则表达式验证手机号
var re = /^1[3-9]\d{9}$/;
var span = document.getElementById("span");
var but = document.getElementById("but");
var t = 10;
var time;
function fun(){
var inp = document.getElementById("inp").value;
if(re.test(inp)){
span.innerHTML = ""; // 清空提示
time = setInterval(wait, 1000); // 启动倒计时
but.setAttribute("disabled", "disabled"); // 禁用按钮
} else {
console.log(inp);
span.innerHTML = "*手机号不正确";
span.style.color = "red";
}
}
function wait(){
if(t == 0){
clearInterval(time); // 清除定时器
but.removeAttribute("disabled"); // 启用按钮
but.innerHTML = "发送验证码";
t = 10; // 重置倒计时
} else {
but.innerHTML = "等待" + t + "秒后重新发送";
t--;
}
}
</script>
</body>
</html>
```
二、核心知识点解析
1. 正则表达式验证
代码中使用了正则表达式 `/^1[3-9]\d{9}$/` 来验证中国大陆手机号:
- `^1`:表示字符串必须以数字1开头(中国大陆手机号第一位固定为1)
- `[3-9]`:第二位数字必须是3到9之间的任意一个(这是运营商号段的范围)
- `\d{9}`:后面跟着9位数字(总长度为11位)
- `$`:表示字符串结束
js常用的正则表达式:https://blog.csdn.net/weixin_72163837/article/details/148084057?spm=1011.2415.3001.5331
JavaScript 中使用正则表达式的 `test()` 方法来检查字符串是否匹配模式:
```javascript
var re = /^1[3-9]\d{9}$/;
if (re.test(phoneNumber)) {
// 格式正确
} else {
// 格式错误
}
```
2. DOM 操作
代码中通过 `document.getElementById()` 方法获取页面元素:
```javascript
var inp = document.getElementById("inp").value; // 获取输入框的值
var span = document.getElementById("span"); // 获取提示信息元素
var but = document.getElementById("but"); // 获取按钮元素
```
通过修改元素的属性和内容来实现交互效果:
- 修改按钮文本:`but.innerHTML = "新的文本";`
- 禁用/启用按钮:
```javascript
but.setAttribute("disabled", "disabled"); // 禁用
but.removeAttribute("disabled"); // 启用
```
- 显示错误提示:
```javascript
span.innerHTML = "*手机号不正确";
span.style.color = "red";
```
3. 定时器的使用
JavaScript 提供了两种定时器函数:
- `setInterval(func, delay)`:每隔指定时间(delay)执行一次函数func
- `setTimeout(func, delay)`:延迟指定时间后执行一次函数
在倒计时功能中,我们使用 `setInterval` 来每秒更新一次倒计时显示:
```javascript
time = setInterval(wait, 1000); // 每秒执行一次wait函数
```
当倒计时结束时,需要使用 `clearInterval` 清除定时器,避免继续执行:
```javascript
clearInterval(time); // 清除定时器
```
4. 变量作用域与闭包
在倒计时功能中,变量 `t` 和 `time` 被定义在全局作用域:
- `t` 用于存储剩余秒数
- `time` 用于存储定时器ID
这样做的好处是可以在不同函数中共享这些变量。不过需要注意的是,如果不妥善管理,可能会导致多次点击按钮时出现倒计时混乱的问题。
更安全的做法是将倒计时逻辑封装在一个函数内部,使用闭包来管理变量:
```javascript
function startCountdown() {
let t = 10; // 局部变量
updateButtonText(t);
const timer = setInterval(() => {
t--;
updateButtonText(t);
if (t <= 0) {
clearInterval(timer);
}
}, 1000);
}
```
三、常见问题与解决方案
1. 倒计时无限循环问题
原代码中可能会出现倒计时结束后按钮恢复但又立即被禁用的情况,这是因为没有正确清除定时器。解决方案是在倒计时结束时调用 `clearInterval(time)`。
2. 多次点击导致多个定时器问题
如果用户在倒计时期间多次点击按钮,会启动多个定时器,导致倒计时显示异常。解决方案是在按钮点击后立即禁用按钮,防止重复点击。
3. 页面刷新后倒计时重置问题
由于 JavaScript 变量存储在内存中,页面刷新后所有变量都会重置。如果需要保持倒计时状态,可以考虑使用 `localStorage` 存储倒计时信息。