密码框眼睛图标显示/隐藏密码功能在Firefox浏览器失效求助
Firefox中密码显示/隐藏切换功能失效的解决方案
我开发了一个密码找回页面,包含两个密码输入框,通过JavaScript实现点击眼睛图标切换密码显示与隐藏的功能。该功能在Chrome和Edge浏览器中正常工作,但在Firefox里完全无法使用。
现有代码
JavaScript 逻辑
function togglePasswordVisibility(inputId, iconId) { var passwordInput = document.getElementById(inputId); var eyeIcon = document.getElementById(iconId); if (passwordInput.type === 'password') { passwordInput.type = 'text'; eyeIcon.classList.remove('fa-eye'); eyeIcon.classList.add('fa-eye-slash'); } else { passwordInput.type = 'password'; eyeIcon.classList.remove('fa-eye-slash'); eyeIcon.classList.add('fa-eye'); } }
CSHTML 页面代码
<div class="form-group mt-4"> <label class="mb-1"><strong>Password</strong></label> @Html.PasswordFor(m => m.Password, new { @class = "form-control thin-placeholder", @placeholder = "Please enter password", @autofocus = "autofocus", @id = "fakePassword" }) <i id="toggler" class="far fa-eye toggle-password" onclick="togglePasswordVisibility('fakePassword', 'toggler')"></i> @Html.ValidationMessageFor(m => m.Password, "", new { @class = "text-danger", @maxlength = 50 }) </div> <div class="form-group mt-4"> <label class="mb-1"><strong>Confirm Password</strong></label> @Html.PasswordFor(m => m.ConfirmPassword, new { @class = "form-control thin-placeholder", @placeholder = "Please enter confirm password", @id = "confirmfakePassword" }) <i id="toggler1" class="far fa-eye toggle-password" onclick="togglePasswordVisibility('confirmfakePassword', 'toggler1')"></i> @Html.ValidationMessageFor(m => m.ConfirmPassword, "", new { @class = "text-danger", @maxlength = 50 }) </div>
问题原因
Firefox浏览器出于安全策略限制,不允许动态修改服务器端生成的password类型输入框的type属性(比如通过@Html.PasswordFor渲染的输入框)。而Chrome和Edge对这类操作的限制更为宽松,因此功能在这两个浏览器中正常。
解决方案
方案1:使用setAttribute操作type属性
修改JavaScript函数,用标准DOM属性方法setAttribute和getAttribute替代直接修改type属性,绕过Firefox的限制:
function togglePasswordVisibility(inputId, iconId) { var passwordInput = document.getElementById(inputId); var eyeIcon = document.getElementById(iconId); if (passwordInput.getAttribute('type') === 'password') { passwordInput.setAttribute('type', 'text'); eyeIcon.classList.remove('fa-eye'); eyeIcon.classList.add('fa-eye-slash'); } else { passwordInput.setAttribute('type', 'password'); eyeIcon.classList.remove('fa-eye-slash'); eyeIcon.classList.add('fa-eye'); } }
方案2:双输入框切换显示(更稳妥)
如果方案1仍有问题,可以采用重叠的password和text输入框,通过切换显示状态实现功能,同时保持输入值同步:
修改后的CSHTML:
<div class="form-group mt-4 position-relative"> <label class="mb-1"><strong>Password</strong></label> @Html.PasswordFor(m => m.Password, new { @class = "form-control thin-placeholder", @placeholder = "Please enter password", @autofocus = "autofocus", @id = "passwordInput" }) <input type="text" id="passwordTextInput" class="form-control thin-placeholder position-absolute top-0 start-0 w-100" placeholder="Please enter password" style="display: none;"> <i id="toggler" class="far fa-eye toggle-password" onclick="togglePasswordVisibility('passwordInput', 'passwordTextInput', 'toggler')"></i> @Html.ValidationMessageFor(m => m.Password, "", new { @class = "text-danger", @maxlength = 50 }) </div> <div class="form-group mt-4 position-relative"> <label class="mb-1"><strong>Confirm Password</strong></label> @Html.PasswordFor(m => m.ConfirmPassword, new { @class = "form-control thin-placeholder", @placeholder = "Please enter confirm password", @id = "confirmPasswordInput" }) <input type="text" id="confirmPasswordTextInput" class="form-control thin-placeholder position-absolute top-0 start-0 w-100" placeholder="Please enter confirm password" style="display: none;"> <i id="toggler1" class="far fa-eye toggle-password" onclick="togglePasswordVisibility('confirmPasswordInput', 'confirmPasswordTextInput', 'toggler1')"></i> @Html.ValidationMessageFor(m => m.ConfirmPassword, "", new { @class = "text-danger", @maxlength = 50 }) </div>
对应的JavaScript:
function togglePasswordVisibility(passwordId, textId, iconId) { var passwordInput = document.getElementById(passwordId); var textInput = document.getElementById(textId); var eyeIcon = document.getElementById(iconId); // 移除之前的监听,避免重复绑定 textInput.removeEventListener('input', syncPasswordValues); passwordInput.removeEventListener('input', syncTextValues); if (passwordInput.style.display !== 'none') { // 切换到文本显示模式 passwordInput.style.display = 'none'; textInput.style.display = 'block'; textInput.value = passwordInput.value; eyeIcon.classList.remove('fa-eye'); eyeIcon.classList.add('fa-eye-slash'); // 绑定同步事件 textInput.addEventListener('input', syncPasswordValues); } else { // 切换到密码隐藏模式 passwordInput.style.display = 'block'; textInput.style.display = 'none'; passwordInput.value = textInput.value; eyeIcon.classList.remove('fa-eye-slash'); eyeIcon.classList.add('fa-eye'); // 绑定同步事件 passwordInput.addEventListener('input', syncTextValues); } // 同步文本框到密码框 function syncPasswordValues() { passwordInput.value = textInput.value; } // 同步密码框到文本框 function syncTextValues() { textInput.value = passwordInput.value; } }
验证说明
方案1是最简便的修复方式,大多数情况下能直接解决Firefox的兼容性问题。如果遇到特殊场景(比如更严格的安全策略),方案2的双输入框方式更稳定,完全避开了修改type属性的限制。
内容的提问来源于stack exchange,提问作者gokul
相关产品推荐
相关产品推荐

