Files
dns-server/.trae/documents/修复web屏蔽管理页面一直显示处理中遮罩的问题.md
2025-11-28 18:41:55 +08:00

3.8 KiB
Raw Blame History

问题分析

通过代码分析我发现web屏蔽管理页面点击后一直显示处理中灰色遮罩的原因有两个

  1. JavaScript错误导致hideLoading()不被调用

    • loadLocalRules()函数尝试访问document.getElementById('local-rules-count')但该元素在HTML中不存在
    • loadRemoteRules()函数尝试访问document.getElementById('remote-rules-count')但该元素在HTML中不存在
    • setupShieldEventListeners()函数尝试访问document.getElementById('view-local-rules-btn')document.getElementById('view-remote-rules-btn')但这些元素在HTML中不存在
    • 这些JavaScript错误会导致函数执行中断从而使hideLoading()不被调用,加载遮罩一直显示
  2. 竞态条件问题

    • initShieldPage()函数并行调用三个异步函数:loadShieldStats()loadLocalRules()loadRemoteBlacklists()
    • 每个异步函数都会调用showLoading(),而showLoading()会先调用hideLoading()来移除现有加载状态,然后创建一个新的加载状态
    • 这种并行调用可能导致竞态条件,使最后一个加载遮罩无法被正确销毁

修复计划

  1. 修改loadLocalRules()函数添加元素存在性检查避免JavaScript错误
  2. 修改loadRemoteRules()函数添加元素存在性检查避免JavaScript错误
  3. 修改setupShieldEventListeners()函数添加元素存在性检查避免JavaScript错误
  4. 修改initShieldPage()函数:确保只创建一个加载遮罩,并在所有异步函数完成后销毁它

修复步骤

步骤1修改loadLocalRules()函数

shield.js文件中,修改loadLocalRules()函数,添加元素存在性检查:

// 更新本地规则数量显示
if (document.getElementById('local-rules-count')) {
  document.getElementById('local-rules-count').textContent = data.localRulesCount || 0;
}

步骤2修改loadRemoteRules()函数

shield.js文件中,修改loadRemoteRules()函数,添加元素存在性检查:

// 更新远程规则数量显示
if (document.getElementById('remote-rules-count')) {
  document.getElementById('remote-rules-count').textContent = data.remoteRulesCount || 0;
}

步骤3修改setupShieldEventListeners()函数

shield.js文件中,修改setupShieldEventListeners()函数,添加元素存在性检查:

// 添加切换查看本地规则和远程规则的事件监听
if (document.getElementById('view-local-rules-btn')) {
  document.getElementById('view-local-rules-btn').addEventListener('click', loadLocalRules);
}

if (document.getElementById('view-remote-rules-btn')) {
  document.getElementById('view-remote-rules-btn').addEventListener('click', loadRemoteRules);
}

步骤4修改initShieldPage()函数

shield.js文件中,修改initShieldPage()函数,确保只创建一个加载遮罩,并在所有异步函数完成后销毁它:

// 初始化屏蔽管理页面
async function initShieldPage() {
  showLoading('加载屏蔽管理数据...');
  try {
    // 并行加载所有数据
    await Promise.all([
      loadShieldStats(),
      loadLocalRules(),
      loadRemoteBlacklists()
    ]);
    // 设置事件监听器
    setupShieldEventListeners();
  } finally {
    hideLoading();
  }
}

步骤5修改异步函数移除内部的showLoading()hideLoading()调用

shield.js文件中,修改loadShieldStats()loadLocalRules()loadRemoteBlacklists()函数,移除内部的showLoading()hideLoading()调用,只保留数据加载逻辑。

预期效果

修复后web屏蔽管理页面点击后

  1. 只会显示一个加载遮罩
  2. 不会出现JavaScript错误
  3. 所有数据加载完成后,加载遮罩会被正确隐藏
  4. 页面会正常显示屏蔽管理设置内容