目录
所需要的组件
<input>标签,<button>标签,<script>标签
详情使用参考:HTML 教程 | 菜鸟教程
案例需求
编写一个程序,最多允许用户尝试登录 3 次。
每次提示输入用户名和密码(假设正确用户名为 `"admin"`,密码为 `"123456"`),
如果输入错误超过 3 次则锁定账户。
思路
利用button按钮实现点击事件获取输入框获取的值进行条件判断是否满足登录要求实现登录功能
错误案例及问题
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div>
账户名:<input type="text" id="username">
密码:<input type="password" id="password">
<button onclick="login()">登录</button>
<p id="output"></p>
</div>
<script>
// let count = 0;
function login() {
let username = document.getElementById('username').value;
let password = document.getElementById('password').value;
for(let i = 0; i<3;i++){
if(username === 'admin' && password === '123456'){
document.getElementById('output').textContent = '登录成功';
console.log(i)
break;
}else{
document.getElementById('output').textContent = '登录失败,请重新输入(剩余尝试次数:' + (3 - i) + ')';
}
if (i === 2){
document.getElementById('output').textContent = '密码错误已达3次,账户已锁定';
}
}
}
</script>
</body>
</html>
应该有人像我一样看到案例需求的第一眼就会这么写,然后开始第一次运行
输入正确的,出现
等到输入错误的值的时候
不对,明明我只提交了一次,错误的话应该是输出重新输入,还剩余一次的的提示啊,为什么会直接进入第三次的锁定,导致想不明白。
为了一探究竟我们需要打印i的值来确定问题所在
于是将代码修改成如下图这样
<script>
// let count = 0;
function login() {
let username = document.getElementById('username').value;
let password = document.getElementById('password').value;
for(let i = 0; i<3;i++){
console.log(i)
if(username === 'admin' && password === '123456'){
document.getElementById('output').textContent = '登录成功';
console.log(i)
break;
}else{
document.getElementById('output').textContent = '登录失败,请重新输入(剩余尝试次数:' + (3 - i) + ')';
console.log(i)
}
if (i === 2){
document.getElementById('output').textContent = '密码错误已达3次,账户已锁定';
}
console.log(i)
}
}
</script>
运行提交
会清晰发现打印了多次重复结果。
原因是因为for()的循环体 ,当条件不满足包含break语句的if判断语句的时候,所有循环体都会执行,就导致了会直接运行到最后的结果,其实会提示重新输入的语句这一提示的,但是由于计算机的计算速度很快,会直接到最后的结果进行直接覆盖
JavaScript 的执行机制是事件驱动 + 单线程的,它遵循如下逻辑:
- 用户点击按钮,触发
login()
函数; - 浏览器立即执行
login()
中的所有代码,包括for
循环; - 循环内的所有迭代都会在一次点击中完成,不会等待用户再次输入;
- 因此,即使你希望“每次点击只验证一次”,但循环的存在会导致“单次点击验证多次
JavaScript 中的事件处理函数(如 onclick
)是同步执行的,不会暂停等待用户交互;如果想实现“多次尝试”,应该依靠外部状态变量(如 attemptCount
)而不是 循环体;
修改思路
知道了问题所在就给我们提供了修改思路
进行单次提交进行累加次数计算,也就是不使用循环体,进行条件判断
案例代码提供
<script>
let count = 0;
function login() {
let username = document.getElementById('username').value;
let password = document.getElementById('password').value;
if (count >= 3) {
document.getElementById('output').textContent = '账户已锁定,无法继续尝试';
return;
}
if (username === 'admin' && password === '123456') {
document.getElementById('output').textContent = '登录成功';
} else {
count++;
}
if (count === 3) {
document.getElementById('output').textContent = '密码错误已达3次,账户已锁定';
} else {
document.getElementById('output').textContent = '登录失败,请重新输入(剩余尝试次数:' + (3 - count) + ')';
}
}
</script>
运行结果:
到这里也就完成了该案例了。