JavaScript按钮禁用作为while循环条件时仅运行一次的问题
密码生成器循环仅执行一次的问题排查与修复
核心问题出在你循环里的return newPassword.appendChild(result)语句——return会直接终止整个generatePass函数,所以第一次循环执行到这里就结束了,自然不会继续生成密码。只保留console.log('yes')时没有return,所以循环能一直跑。
另外还有几个小问题会影响功能或代码健壮性,一起给你修复:
具体修改点
- 删掉循环内的
return:newPassword.appendChild(result)不需要返回值,直接执行即可,return会打断循环。 - 将
sleep函数移到generatePass外面:避免每次调用生成函数都重新定义一遍sleep。 - 把
pass.value转为数字:pass.value是字符串类型,直接和数字i比较会出问题,用Number(pass.value)转换。 - 提前缓存按钮元素:不用每次循环都
querySelector,提升性能。 - 移除循环内重复设置按钮禁用的代码:函数开头已经设置过,没必要重复执行。
修复后的完整代码
const pass = document.querySelector('#pass') const newPassword = document.querySelector('#newPassword') const goalBtn = document.querySelector('#Goal') // 把sleep移到外面,避免重复定义 async function sleep(seconds) { return new Promise((resolve) => setTimeout(resolve, seconds * 1000)) } async function generatePass(){ goalBtn.disabled = true while (goalBtn.disabled) { await sleep(1) console.log('yes') newPassword.innerHTML = '' if(pass.value === ''){ alert('Choose the password size!') goalBtn.disabled = false // 弹窗后恢复按钮状态,避免卡死 return } const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" let password = "" const passLength = Number(pass.value) // 转为数字 for(let i = 0, n = charset.length; i < passLength; ++i){ password += charset.charAt(Math.floor(Math.random() * n)) } const result = document.createTextNode(password) newPassword.appendChild(result) // 去掉return } } function breakgeneratePass(){ goalBtn.disabled = false }
额外优化说明
- 弹窗后添加了
goalBtn.disabled = false,避免用户输入为空弹窗后,按钮一直处于禁用状态无法继续操作。 - 把循环里的
var改成let,避免变量提升导致的潜在问题。
内容的提问来源于stack exchange,提问作者BOB CÓMUNISTA
相关产品推荐
相关产品推荐

