3.8 KiB
3.8 KiB
问题分析
通过代码分析,我发现web屏蔽管理页面点击后一直显示处理中灰色遮罩的原因有两个:
-
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()不被调用,加载遮罩一直显示
-
竞态条件问题:
initShieldPage()函数并行调用三个异步函数:loadShieldStats()、loadLocalRules()和loadRemoteBlacklists()- 每个异步函数都会调用
showLoading(),而showLoading()会先调用hideLoading()来移除现有加载状态,然后创建一个新的加载状态 - 这种并行调用可能导致竞态条件,使最后一个加载遮罩无法被正确销毁
修复计划
- 修改
loadLocalRules()函数:添加元素存在性检查,避免JavaScript错误 - 修改
loadRemoteRules()函数:添加元素存在性检查,避免JavaScript错误 - 修改
setupShieldEventListeners()函数:添加元素存在性检查,避免JavaScript错误 - 修改
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屏蔽管理页面点击后:
- 只会显示一个加载遮罩
- 不会出现JavaScript错误
- 所有数据加载完成后,加载遮罩会被正确隐藏
- 页面会正常显示屏蔽管理设置内容