You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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;
}

问题原因

  1. DOM加载时机不匹配:Keycloak部分表单元素是动态生成的,window.onload触发时目标密码元素可能还未渲染,导致无法找到元素。
  2. 图标切换逻辑缺失:仅切换bi-eye类,未处理bi-eye-slash的切换,图标显示状态异常。
  3. 可见性判断不准确:仅通过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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 03:15:49