Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
157 changes: 157 additions & 0 deletions .kiro/specs/frontend-navigation-site/ICON_FALLBACK_DEMO.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
# 图标加载失败处理演示

## 快速测试方法

### 方法 1:使用浏览器开发者工具

1. 打开网站
2. 按 F12 打开开发者工具
3. 切换到 Console 标签
4. 运行以下代码添加测试链接:

```javascript
// 测试 1:无效的自定义图标 URL
const testLink1 = {
id: 'test-1',
name: '测试:无效图标',
url: 'https://github.com',
description: '这个链接使用了无效的图标URL',
category: '主页',
icon: 'https://invalid-domain-12345.com/icon.png',
backgroundColor: '#1890ff',
iconScale: 0.7,
tags: [],
order: 0,
createdAt: Date.now(),
updatedAt: Date.now()
};

// 测试 2:无效的域名(favicon 也会失败)
const testLink2 = {
id: 'test-2',
name: '测试:完全失败',
url: 'https://invalid-domain-99999.com',
description: '这个链接的图标和favicon都会失败',
category: '主页',
icon: 'https://invalid-domain-12345.com/icon.png',
backgroundColor: '#52c41a',
iconScale: 0.7,
tags: [],
order: 0,
createdAt: Date.now(),
updatedAt: Date.now()
};

// 测试 3:只依赖 favicon(应该成功)
const testLink3 = {
id: 'test-3',
name: '测试:Favicon回退',
url: 'https://www.google.com',
description: '这个链接没有自定义图标,应该显示Google的favicon',
category: '主页',
backgroundColor: '#4285f4',
iconScale: 0.7,
tags: [],
order: 0,
createdAt: Date.now(),
updatedAt: Date.now()
};

// 添加到 localStorage
const existingLinks = JSON.parse(localStorage.getItem('navigation-links') || '[]');
existingLinks.push(testLink1, testLink2, testLink3);
localStorage.setItem('navigation-links', JSON.stringify(existingLinks));

// 刷新页面
location.reload();
```

### 方法 2:通过 UI 手动添加

1. 点击页面上的"添加链接"按钮
2. 填写以下信息:

**测试链接 1:无效图标**
- 名称:测试:无效图标
- 地址:https://github.com
- 描述:这个链接使用了无效的图标URL
- 图标:https://invalid-domain-12345.com/icon.png
- 背景色:#1890ff

**测试链接 2:完全失败**
- 名称:测试:完全失败
- 地址:https://invalid-domain-99999.com
- 描述:这个链接的图标和favicon都会失败
- 图标:https://invalid-domain-12345.com/icon.png
- 背景色:#52c41a

**测试链接 3:Favicon回退**
- 名称:测试:Favicon回退
- 地址:https://www.google.com
- 描述:这个链接没有自定义图标,应该显示Google的favicon
- 图标:(留空)
- 背景色:#4285f4

## 预期结果

### 测试链接 1(无效图标)
- ✅ 不显示破损的图片图标
- ✅ 自动回退到 GitHub 的 favicon
- ✅ 控制台显示:`图标加载失败: https://invalid-domain-12345.com/icon.png`

### 测试链接 2(完全失败)
- ✅ 不显示破损的图片图标
- ✅ 显示默认的链接图标(LinkOutlined)
- ✅ 控制台显示两条警告:
- `图标加载失败: https://invalid-domain-12345.com/icon.png`
- `Favicon 加载失败: [favicon URL]`

### 测试链接 3(Favicon回退)
- ✅ 显示 Google 的 favicon
- ✅ 图标清晰,没有破损

## 清理测试数据

测试完成后,可以通过以下方式清理测试数据:

### 方法 1:通过 UI 删除
右键点击测试链接卡片,选择"删除"

### 方法 2:通过控制台清理
```javascript
// 删除所有测试链接
const links = JSON.parse(localStorage.getItem('navigation-links') || '[]');
const cleanedLinks = links.filter(link => !link.name.startsWith('测试:'));
localStorage.setItem('navigation-links', JSON.stringify(cleanedLinks));
location.reload();
```

## 技术说明

### 修复前的问题
```typescript
// 问题代码:使用 display: 'none' 隐藏
<img
src={src}
style={{ display: hasError ? 'none' : 'block' }}
onError={() => setHasError(true)}
/>
```

浏览器可能在设置 `display: 'none'` 之前短暂显示破损图标。

### 修复后的方案
```typescript
// 解决方案:条件渲染,完全不渲染失败的元素
if (hasError && (faviconError || !fallbackUrl)) {
return <DefaultIcon />;
}

if (hasError && fallbackUrl && !faviconError) {
return <img src={fallbackUrl} onError={() => setFaviconError(true)} />;
}

return <img src={src} onError={() => setHasError(true)} />;
```

这样可以确保失败的 `<img>` 元素完全不会被渲染到 DOM 中。
Loading