Keycloak密码框显示/隐藏密码功能失效问题排查求助
Keycloak密码显示/隐藏切换功能修复方案
问题描述
修改Keycloak的script.js添加密码框显示/隐藏切换功能后,功能无法正常运行,原代码如下:
原script.js代码
// Rudimentary method for adding a password reveal button. window.onload = function() { var fToggle = function($password, e) { e.preventDefault(); const type = $password.getAttribute('type') === 'password' ? 'text' : 'password'; $password.setAttribute('type', type); this.classList.toggle('bi-eye'); }; var createReveal = function(passwordId, toggleId) { var password = document.getElementById(passwordId); if ((password) && (password.style) && (password.style.display !== 'none')){ var icon = document.createElement("i"); icon.id = toggleId; icon.classList.add('password-reveal', 'bi', 'bi-eye-slash'); icon.addEventListener('click', fToggle.bind(icon, password)); password.parentNode.insertBefore(icon, password.nextSibling); } }; createReveal('password', 'togglePassword'); createReveal('password-new', 'togglePasswordNew'); createReveal('password-confirm', 'togglePasswordConfirm'); };
原CSS代码
.password-reveal { color: #5500B3; margin-left: -40px; font-size: 20px; cursor: pointer; }
问题原因
- DOM加载时机不匹配:Keycloak部分表单元素是动态生成的,
window.onload触发时目标密码元素可能还未渲染,导致无法找到元素。 - 图标切换逻辑缺失:仅切换
bi-eye类,未处理bi-eye-slash的切换,图标显示状态异常。 - 可见性判断不准确:仅通过
element.style.display判断元素可见性,无法识别CSS类控制隐藏的场景。
修复方案
修复后的script.js代码
// 密码显示/隐藏切换功能 document.addEventListener('DOMContentLoaded', function() { // 切换密码显示状态的函数 const togglePassword = function(passwordEl, e) { e.preventDefault(); // 切换输入框类型 const newType = passwordEl.getAttribute('type') === 'password' ? 'text' : 'password'; passwordEl.setAttribute('type', newType); // 同步切换图标样式 this.classList.toggle('bi-eye'); this.classList.toggle('bi-eye-slash'); }; // 创建密码显示按钮 const createRevealButton = function(passwordId, toggleId) { const passwordEl = document.getElementById(passwordId); // 检查元素是否存在 if (!passwordEl) return; // 用计算样式判断元素实际可见性 const isVisible = window.getComputedStyle(passwordEl).display !== 'none'; if (!isVisible) return; // 避免重复创建按钮 if (document.getElementById(toggleId)) return; // 创建图标元素 const icon = document.createElement('i'); icon.id = toggleId; icon.classList.add('password-reveal', 'bi', 'bi-eye-slash'); // 绑定点击事件 icon.addEventListener('click', togglePassword.bind(icon, passwordEl)); // 插入到密码框后方 passwordEl.parentNode.insertBefore(icon, passwordEl.nextSibling); }; // 初始化所有密码框的显示按钮 const initPasswordReveal = function() { createRevealButton('password', 'togglePassword'); createRevealButton('password-new', 'togglePasswordNew'); createRevealButton('password-confirm', 'togglePasswordConfirm'); }; // 首次初始化 initPasswordReveal(); // 监听DOM变化,适配Keycloak动态渲染的表单元素 const observer = new MutationObserver(function(mutations) { mutations.forEach(function(mutation) { if (mutation.addedNodes.length > 0) { initPasswordReveal(); } }); }); // 监听body下的所有DOM变化 observer.observe(document.body, { childList: true, subtree: true }); });
关键修复点
- 适配动态DOM:用
DOMContentLoaded提前触发初始化,搭配MutationObserver监听DOM变化,确保动态生成的密码元素也能绑定切换按钮。 - 完善图标切换:同时切换
bi-eye和bi-eye-slash类,保证图标状态与密码显示状态一致。 - 准确判断可见性:使用
window.getComputedStyle获取元素实际显示状态,覆盖CSS类控制隐藏的场景。 - 避免重复创建:添加按钮ID检查,防止重复生成切换图标。
注意事项
确保Keycloak主题中已引入Bootstrap Icons资源,否则bi-eye、bi-eye-slash类对应的图标无法正常显示。
内容的提问来源于stack exchange,提问作者banto
相关产品推荐
相关产品推荐

