90 lines
3.8 KiB
Markdown
90 lines
3.8 KiB
Markdown
## 问题分析
|
||
|
||
通过代码分析,我发现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()`函数,添加元素存在性检查:
|
||
|
||
```javascript
|
||
// 更新本地规则数量显示
|
||
if (document.getElementById('local-rules-count')) {
|
||
document.getElementById('local-rules-count').textContent = data.localRulesCount || 0;
|
||
}
|
||
```
|
||
|
||
### 步骤2:修改`loadRemoteRules()`函数
|
||
在`shield.js`文件中,修改`loadRemoteRules()`函数,添加元素存在性检查:
|
||
|
||
```javascript
|
||
// 更新远程规则数量显示
|
||
if (document.getElementById('remote-rules-count')) {
|
||
document.getElementById('remote-rules-count').textContent = data.remoteRulesCount || 0;
|
||
}
|
||
```
|
||
|
||
### 步骤3:修改`setupShieldEventListeners()`函数
|
||
在`shield.js`文件中,修改`setupShieldEventListeners()`函数,添加元素存在性检查:
|
||
|
||
```javascript
|
||
// 添加切换查看本地规则和远程规则的事件监听
|
||
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()`函数,确保只创建一个加载遮罩,并在所有异步函数完成后销毁它:
|
||
|
||
```javascript
|
||
// 初始化屏蔽管理页面
|
||
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. 页面会正常显示屏蔽管理设置内容 |