目錄
案例需求
思路
錯誤案例及問題
修改思路
案例提供
所需要的組件
<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>
運行結果:
到這里也就完成了該案例了。