如何让Bootstrap bi-eye在页面的两个密码字段正常工作?
解决密码确认字段的显隐切换问题
你的问题出在两个核心点:
- HTML里两个眼睛图标用了同一个id(
togglePassword),HTML规则要求id必须唯一,document.querySelector('#togglePassword')只会选中第一个图标,第二个图标根本没绑定点击事件。 - 原JS代码只针对
#password输入框写死了逻辑,完全没处理确认密码框。
给你两种解决方案,推荐第二种(更灵活,以后加更多密码框也不用改JS):
方案一:给每个图标单独设id(新手快速适配)
先修改HTML,把第二个图标id改成togglePasswordConfirm:
<form method="post" action="process-reset-password.php" id="forgot2" novalidate> <div> <input type="hidden" name="token" value="<?= htmlspecialchars($token) ?>"> <label for="password">New password</label><br> <input type="password" name="password" id="password" autocomplete="off" /> <i class="bi bi-eye-slash" id="togglePassword"></i> </div> <br> <div> <label for="password_confirmation">Repeat password</label><br> <input type="password" name="password_confirmation" id="password_confirmation" autocomplete="off" /> <i class="bi bi-eye-slash" id="togglePasswordConfirm"></i> </div> <br> <button>Send</button> </form>
再修改JS,给两个图标分别绑定事件:
// 处理第一个密码框 const togglePassword = document.querySelector('#togglePassword'); const password = document.querySelector('#password'); togglePassword.addEventListener('click', (e) => { const type = password.getAttribute('type') === 'password' ? 'text' : 'password'; password.setAttribute('type', type); e.target.classList.toggle('bi-eye'); }); // 处理确认密码框 const togglePasswordConfirm = document.querySelector('#togglePasswordConfirm'); const passwordConfirm = document.querySelector('#password_confirmation'); togglePasswordConfirm.addEventListener('click', (e) => { const type = passwordConfirm.getAttribute('type') === 'password' ? 'text' : 'password'; passwordConfirm.setAttribute('type', type); e.target.classList.toggle('bi-eye'); });
方案二:用class统一处理(更优雅,扩展性强)
把图标改成用class标识,去掉重复id,这样不管有多少个密码框,JS都能自动处理:
<form method="post" action="process-reset-password.php" id="forgot2" novalidate> <div> <input type="hidden" name="token" value="<?= htmlspecialchars($token) ?>"> <label for="password">New password</label><br> <input type="password" name="password" id="password" autocomplete="off" /> <i class="bi bi-eye-slash toggle-password"></i> </div> <br> <div> <label for="password_confirmation">Repeat password</label><br> <input type="password" name="password_confirmation" id="password_confirmation" autocomplete="off" /> <i class="bi bi-eye-slash toggle-password"></i> </div> <br> <button>Send</button> </form>
然后JS只需要写一次逻辑,遍历所有切换图标:
// 获取所有密码切换图标 const toggleButtons = document.querySelectorAll('.toggle-password'); // 给每个图标绑定点击事件 toggleButtons.forEach(button => { button.addEventListener('click', (e) => { // 找到当前图标对应的密码输入框(图标在输入框的下一个兄弟元素,用previousElementSibling获取) const passwordInput = e.target.previousElementSibling; // 切换输入框的type const type = passwordInput.getAttribute('type') === 'password' ? 'text' : 'password'; passwordInput.setAttribute('type', type); // 切换图标样式 e.target.classList.toggle('bi-eye'); }); });
这个方法的好处是,以后再增加密码输入框,只要给对应的图标加上toggle-password类,JS不用改就能自动生效。
你之前尝试修改变量名失效,就是因为重复id导致事件只绑定了第一个图标,而且原JS逻辑只针对一个输入框,现在用上面的方法就能解决问题了。
内容的提问来源于stack exchange,提问作者user28424958
相关产品推荐
相关产品推荐

