|
@@ -4,18 +4,18 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
|
|
|
|
|
|
|
|
## 项目概述
|
|
## 项目概述
|
|
|
|
|
|
|
|
-CJYDocs 是一个基于 Node.js + Express 的轻量级 Markdown 文档管理和渲染系统,采用前后端分离架构。核心特点包括:
|
|
|
|
|
-- 通过解析 `docs/index.md` 配置文件实现文档的层级化管理
|
|
|
|
|
-- 支持在线编辑功能,智能光标定位
|
|
|
|
|
|
|
+CJYDocs 是一个基于 Node.js + Express 的轻量级 Markdown 文档管理和渲染系统,采用前后端分离架构。核心特点包括:
|
|
|
|
|
+- 通过解析 `index.md` 配置文件实现文档的层级化管理
|
|
|
|
|
+- 支持在线编辑功能,智能光标定位
|
|
|
- 全文搜索、TOC 目录、响应式设计
|
|
- 全文搜索、TOC 目录、响应式设计
|
|
|
-- 高性能优化:DOM 缓存、事件委托、IntersectionObserver
|
|
|
|
|
|
|
+- 高性能优化: DOM 缓存、事件委托、IntersectionObserver
|
|
|
|
|
|
|
|
## 开发命令
|
|
## 开发命令
|
|
|
|
|
|
|
|
### 启动服务器
|
|
### 启动服务器
|
|
|
```bash
|
|
```bash
|
|
|
npm start # 生产模式启动
|
|
npm start # 生产模式启动
|
|
|
-npm run dev # 开发模式启动(使用 nodemon 自动重启)
|
|
|
|
|
|
|
+npm run dev # 开发模式启动(使用 nodemon 自动重启)
|
|
|
```
|
|
```
|
|
|
|
|
|
|
|
服务器默认运行在 `http://localhost:3000`
|
|
服务器默认运行在 `http://localhost:3000`
|
|
@@ -37,11 +37,11 @@ npm install
|
|
|
数据层 (docs/)
|
|
数据层 (docs/)
|
|
|
```
|
|
```
|
|
|
|
|
|
|
|
-### 文档配置核心:index.md 解析
|
|
|
|
|
|
|
+### 文档配置核心: index.md 解析
|
|
|
|
|
|
|
|
-**关键文件**: `docs/index.md`
|
|
|
|
|
|
|
+**关键文件**: `./index.md` (项目根目录,NOT docs/index.md)
|
|
|
|
|
|
|
|
-系统的文档结构完全由 `index.md` 定义,格式如下:
|
|
|
|
|
|
|
+系统的文档结构完全由 `index.md` 定义,格式如下:
|
|
|
|
|
|
|
|
```markdown
|
|
```markdown
|
|
|
[分类名称]
|
|
[分类名称]
|
|
@@ -54,14 +54,14 @@ npm install
|
|
|
|
|
|
|
|
**解析逻辑** (`server.js:247-282`):
|
|
**解析逻辑** (`server.js:247-282`):
|
|
|
- `[分类名]` → 对应 `docs/` 下的目录名
|
|
- `[分类名]` → 对应 `docs/` 下的目录名
|
|
|
-- `编号: 文档名.md` → 文档项,支持多级编号(如 1.1.1)
|
|
|
|
|
-- `level` 通过点号数量计算:`1` = level 0, `1.1` = level 1, `1.1.1` = level 2
|
|
|
|
|
-- 返回结构:`{ name, docs: [{ number, name, level, fullName }] }`
|
|
|
|
|
|
|
+- `编号: 文档名.md` → 文档项,支持多级编号(如 1.1.1)
|
|
|
|
|
+- `level` 通过点号数量计算: `1` = level 0, `1.1` = level 1, `1.1.1` = level 2
|
|
|
|
|
+- 返回结构: `{ name, docs: [{ number, name, level, fullName }] }`
|
|
|
|
|
|
|
|
-**重要**:添加新文档时:
|
|
|
|
|
|
|
+**重要**: 添加新文档时:
|
|
|
1. 在 `docs/分类名/` 下创建 `.md` 文件
|
|
1. 在 `docs/分类名/` 下创建 `.md` 文件
|
|
|
-2. 在 `docs/index.md` 中添加对应条目
|
|
|
|
|
-3. 两者必须同时存在,文件名必须匹配
|
|
|
|
|
|
|
+2. 在项目根目录的 `index.md` 中添加对应条目
|
|
|
|
|
+3. 两者必须同时存在,文件名必须匹配
|
|
|
|
|
|
|
|
### 前端架构
|
|
### 前端架构
|
|
|
|
|
|
|
@@ -81,65 +81,65 @@ const DOM = {
|
|
|
};
|
|
};
|
|
|
```
|
|
```
|
|
|
|
|
|
|
|
-所有频繁访问的 DOM 元素都通过此对象缓存,避免重复查询。缓存采用懒加载策略:首次使用时查询并缓存,后续直接使用。
|
|
|
|
|
|
|
+所有频繁访问的 DOM 元素都通过此对象缓存,避免重复查询。缓存采用懒加载策略:首次使用时查询并缓存,后续直接使用。
|
|
|
|
|
|
|
|
**事件委托模式**:
|
|
**事件委托模式**:
|
|
|
-- 导航点击:在 `#doc-nav` 父元素上监听,而非每个导航项
|
|
|
|
|
-- TOC 点击:在 `#toc` 父元素上监听
|
|
|
|
|
-- 优势:减少 90%+ 的事件监听器,降低内存占用
|
|
|
|
|
|
|
+- 导航点击:在 `#doc-nav` 父元素上监听,而非每个导航项
|
|
|
|
|
+- TOC 点击:在 `#toc` 父元素上监听
|
|
|
|
|
+- 优势:减少 90%+ 的事件监听器,降低内存占用
|
|
|
|
|
|
|
|
### API 端点
|
|
### API 端点
|
|
|
|
|
|
|
|
-所有 API 都在 `server.js` 中定义:
|
|
|
|
|
|
|
+所有 API 都在 `server.js` 中定义:
|
|
|
|
|
|
|
|
-- `GET /api/structure` - 获取完整文档结构(解析 index.md,带5秒缓存)
|
|
|
|
|
|
|
+- `GET /api/structure` - 获取完整文档结构(解析 index.md,带5秒缓存)
|
|
|
- `GET /api/category/:category` - 获取指定分类信息
|
|
- `GET /api/category/:category` - 获取指定分类信息
|
|
|
- `GET /api/doc/:category/:docName` - 获取文档内容
|
|
- `GET /api/doc/:category/:docName` - 获取文档内容
|
|
|
-- `PUT /api/doc/:category/:docName` - 保存文档内容(在线编辑)
|
|
|
|
|
|
|
+- `PUT /api/doc/:category/:docName` - 保存文档内容(在线编辑)
|
|
|
- `GET /api/search/:category?q=xxx¤tDoc=yyy` - 搜索文档
|
|
- `GET /api/search/:category?q=xxx¤tDoc=yyy` - 搜索文档
|
|
|
|
|
|
|
|
-**安全机制**:
|
|
|
|
|
-所有用户输入都经过 `sanitizePath()` 清理和 `validatePath()` 验证,防止路径遍历攻击。
|
|
|
|
|
|
|
+**安全机制**:
|
|
|
|
|
+所有用户输入都经过 `sanitizePath()` 清理和 `validatePath()` 验证,防止路径遍历攻击。
|
|
|
|
|
|
|
|
-**缓存策略**:
|
|
|
|
|
-`index.md` 解析结果缓存5秒(`server.js:9-12`),减少文件系统读取频率。
|
|
|
|
|
|
|
+**缓存策略**:
|
|
|
|
|
+`index.md` 解析结果缓存5秒(`server.js:9-12`),减少文件系统读取频率。
|
|
|
|
|
|
|
|
### 关键功能实现
|
|
### 关键功能实现
|
|
|
|
|
|
|
|
#### 1. Markdown 渲染
|
|
#### 1. Markdown 渲染
|
|
|
-使用 `marked.js` + `highlight.js`,配置在 `reader.js:25-38`
|
|
|
|
|
|
|
+使用 `marked.js` + `highlight.js`,配置在 `reader.js:25-38`
|
|
|
|
|
|
|
|
#### 2. TOC 自动生成
|
|
#### 2. TOC 自动生成
|
|
|
-`reader.js:190-270` - 遍历渲染后的 HTML,提取所有 h1-h6 标题,使用 `IntersectionObserver` 实现滚动监听
|
|
|
|
|
|
|
+`reader.js:190-270` - 遍历渲染后的 HTML,提取所有 h1-h6 标题,使用 `IntersectionObserver` 实现滚动监听
|
|
|
|
|
|
|
|
#### 3. 搜索功能
|
|
#### 3. 搜索功能
|
|
|
-- 后端:`server.js:159-244` - 逐行扫描所有 `.md` 文件,返回匹配的行号和上下文片段(最多5个)
|
|
|
|
|
-- 前端:`reader.js:443-785` - 使用 `TreeWalker` API 精确定位到匹配的文本节点并滚动
|
|
|
|
|
-- 搜索历史保存在 `localStorage`,按分类隔离
|
|
|
|
|
-- 搜索防抖 500ms,点击搜索结果后自动关闭搜索框和侧边栏
|
|
|
|
|
|
|
+- 后端: `server.js:159-244` - 逐行扫描所有 `.md` 文件,返回匹配的行号和上下文片段(最多5个)
|
|
|
|
|
+- 前端: `reader.js:443-785` - 使用 `TreeWalker` API 精确定位到匹配的文本节点并滚动
|
|
|
|
|
+- 搜索历史保存在 `localStorage`,按分类隔离
|
|
|
|
|
+- 搜索防抖 500ms,点击搜索结果后自动关闭搜索框和侧边栏
|
|
|
|
|
|
|
|
#### 4. 移动端侧边栏交互
|
|
#### 4. 移动端侧边栏交互
|
|
|
-`reader.js:359-440` - 移动端侧边栏管理逻辑:
|
|
|
|
|
-- **互斥展开**:点击一侧目录按钮时,自动隐藏另一侧已展开的目录,确保同一时间最多只有一个侧边栏展开
|
|
|
|
|
-- **点击外部关闭**:点击文档内容区域或其他目录以外的地方时,所有展开的侧边栏自动隐藏
|
|
|
|
|
-- **响应式行为**:此功能仅在移动端和平板(≤1024px)上启用,桌面端不受影响
|
|
|
|
|
-- **事件处理**:使用 `e.stopPropagation()` 防止事件冒泡,使用 `element.contains()` 精确判断点击位置
|
|
|
|
|
|
|
+`reader.js:359-440` - 移动端侧边栏管理逻辑:
|
|
|
|
|
+- **互斥展开**: 点击一侧目录按钮时,自动隐藏另一侧已展开的目录,确保同一时间最多只有一个侧边栏展开
|
|
|
|
|
+- **点击外部关闭**: 点击文档内容区域或其他目录以外的地方时,所有展开的侧边栏自动隐藏
|
|
|
|
|
+- **响应式行为**: 此功能仅在移动端和平板(≤1024px)上启用,桌面端不受影响
|
|
|
|
|
+- **事件处理**: 使用 `e.stopPropagation()` 防止事件冒泡,使用 `element.contains()` 精确判断点击位置
|
|
|
|
|
|
|
|
#### 5. 性能优化
|
|
#### 5. 性能优化
|
|
|
-- DOM 缓存:减少 60%+ 的查询次数
|
|
|
|
|
-- 事件委托:减少 90%+ 的事件监听器
|
|
|
|
|
-- 搜索防抖:500ms,减少 40% 的 API 请求
|
|
|
|
|
-- `IntersectionObserver`:替代 scroll 事件,性能提升 20-30%
|
|
|
|
|
|
|
+- DOM 缓存:减少 60%+ 的查询次数
|
|
|
|
|
+- 事件委托:减少 90%+ 的事件监听器
|
|
|
|
|
+- 搜索防抖:500ms,减少 40% 的 API 请求
|
|
|
|
|
+- `IntersectionObserver`:替代 scroll 事件,性能提升 20-30%
|
|
|
|
|
|
|
|
#### 6. 在线编辑功能
|
|
#### 6. 在线编辑功能
|
|
|
-`reader.js:820-1095` + `server.js:113-156` - 完整的在线文档编辑系统:
|
|
|
|
|
|
|
+`reader.js:820-1095` + `server.js:113-156` - 完整的在线文档编辑系统:
|
|
|
|
|
|
|
|
-**编辑器特性**:
|
|
|
|
|
-- **智能光标定位** (`reader.js:869-988`):根据当前阅读位置(标题、段落)在编辑器中自动定位到对应的 markdown 源码行
|
|
|
|
|
-- **无缝模式切换**:编辑/预览模式切换时保持滚动位置,自动隐藏渲染内容并显示编辑器
|
|
|
|
|
-- **实时保存**:通过 `PUT /api/doc/:category/:docName` 保存到服务器,保存后自动重新渲染并更新 TOC
|
|
|
|
|
|
|
+**编辑器特性**:
|
|
|
|
|
+- **智能光标定位** (`reader.js:869-988`):根据当前阅读位置(标题、段落)在编辑器中自动定位到对应的 markdown 源码行
|
|
|
|
|
+- **无缝模式切换**:编辑/预览模式切换时保持滚动位置,自动隐藏渲染内容并显示编辑器
|
|
|
|
|
+- **实时保存**:通过 `PUT /api/doc/:category/:docName` 保存到服务器,保存后自动重新渲染并更新 TOC
|
|
|
|
|
|
|
|
-**编辑流程**:
|
|
|
|
|
|
|
+**编辑流程**:
|
|
|
```
|
|
```
|
|
|
点击编辑按钮 → 进入编辑模式
|
|
点击编辑按钮 → 进入编辑模式
|
|
|
↓
|
|
↓
|
|
@@ -156,40 +156,40 @@ saveDocument() → PUT /api/doc/:category/:docName
|
|
|
前端重新渲染 + 退出编辑模式
|
|
前端重新渲染 + 退出编辑模式
|
|
|
```
|
|
```
|
|
|
|
|
|
|
|
-**安全验证**:
|
|
|
|
|
-- 文件必须已存在(不能创建新文件)
|
|
|
|
|
|
|
+**安全验证**:
|
|
|
|
|
+- 文件必须已存在(不能创建新文件)
|
|
|
- 内容类型必须为字符串
|
|
- 内容类型必须为字符串
|
|
|
- 所有路径经过 `sanitizePath()` 和 `validatePath()` 验证
|
|
- 所有路径经过 `sanitizePath()` 和 `validatePath()` 验证
|
|
|
|
|
|
|
|
-**用户体验细节**:
|
|
|
|
|
-- 浮动编辑按钮(右下角)
|
|
|
|
|
-- 防重复提交(保存时禁用按钮)
|
|
|
|
|
-- 成功提示 Toast(2秒后自动消失)
|
|
|
|
|
|
|
+**用户体验细节**:
|
|
|
|
|
+- 浮动编辑按钮(右下角)
|
|
|
|
|
+- 防重复提交(保存时禁用按钮)
|
|
|
|
|
+- 成功提示 Toast(2秒后自动消失)
|
|
|
- 完整的错误处理和提示
|
|
- 完整的错误处理和提示
|
|
|
|
|
|
|
|
## 文件结构
|
|
## 文件结构
|
|
|
|
|
|
|
|
```
|
|
```
|
|
|
cjydocs/
|
|
cjydocs/
|
|
|
-├── server.js # Express 后端(288行)
|
|
|
|
|
-│ # - 所有 API 端点(GET/PUT)
|
|
|
|
|
-│ # - index.md 解析逻辑(带5秒缓存)
|
|
|
|
|
-│ # - 安全验证函数(sanitizePath, validatePath)
|
|
|
|
|
|
|
+├── server.js # Express 后端(288行)
|
|
|
|
|
+│ # - 所有 API 端点(GET/PUT)
|
|
|
|
|
+│ # - index.md 解析逻辑(带5秒缓存)
|
|
|
|
|
+│ # - 安全验证函数(sanitizePath, validatePath)
|
|
|
│ # - 搜索引擎实现
|
|
│ # - 搜索引擎实现
|
|
|
|
|
+├── index.md # 文档结构配置文件(项目根目录)
|
|
|
├── docs/
|
|
├── docs/
|
|
|
-│ ├── index.md # 文档结构配置文件(核心)
|
|
|
|
|
│ └── 分类名/
|
|
│ └── 分类名/
|
|
|
-│ └── 文档.md # 实际文档内容(可通过在线编辑修改)
|
|
|
|
|
|
|
+│ └── 文档.md # 实际文档内容(可通过在线编辑修改)
|
|
|
└── public/
|
|
└── public/
|
|
|
- ├── index.html # 首页(显示分类列表)35行
|
|
|
|
|
- ├── reader.html # 阅读器页面(三栏布局+编辑器)129行
|
|
|
|
|
- ├── css/style.css # 统一样式
|
|
|
|
|
|
|
+ ├── index.html # 首页(显示分类列表)35行
|
|
|
|
|
+ ├── reader.html # 阅读器页面(三栏布局+编辑器)129行
|
|
|
|
|
+ ├── css/style.css # 统一样式
|
|
|
└── js/
|
|
└── js/
|
|
|
- ├── index.js # 首页逻辑(70行)
|
|
|
|
|
- └── reader.js # 阅读器核心逻辑(1113行)
|
|
|
|
|
- # - DOM缓存、事件委托
|
|
|
|
|
- # - 搜索、TOC、侧边栏交互
|
|
|
|
|
- # - 在线编辑器(智能光标定位)
|
|
|
|
|
|
|
+ ├── index.js # 首页逻辑(70行)
|
|
|
|
|
+ └── reader.js # 阅读器核心逻辑(1113行)
|
|
|
|
|
+ # - DOM缓存、事件委托
|
|
|
|
|
+ # - 搜索、TOC、侧边栏交互
|
|
|
|
|
+ # - 在线编辑器(智能光标定位)
|
|
|
```
|
|
```
|
|
|
|
|
|
|
|
## 代码修改指南
|
|
## 代码修改指南
|
|
@@ -198,36 +198,36 @@ cjydocs/
|
|
|
1. 在 `server.js` 中定义新路由
|
|
1. 在 `server.js` 中定义新路由
|
|
|
2. 使用 `sanitizePath()` 清理所有用户输入
|
|
2. 使用 `sanitizePath()` 清理所有用户输入
|
|
|
3. 使用 `validatePath()` 验证文件路径在 `docs/` 目录内
|
|
3. 使用 `validatePath()` 验证文件路径在 `docs/` 目录内
|
|
|
-4. 返回详细的错误信息(但不泄露内部路径)
|
|
|
|
|
|
|
+4. 返回详细的错误信息(但不泄露内部路径)
|
|
|
|
|
|
|
|
### 修改前端逻辑
|
|
### 修改前端逻辑
|
|
|
1. 优先使用 `DOM` 缓存对象获取元素
|
|
1. 优先使用 `DOM` 缓存对象获取元素
|
|
|
2. 使用事件委托替代单独绑定事件
|
|
2. 使用事件委托替代单独绑定事件
|
|
|
3. 对高频操作使用防抖/节流
|
|
3. 对高频操作使用防抖/节流
|
|
|
4. 更新 DOM 时使用 `classList.toggle()` 简化条件判断
|
|
4. 更新 DOM 时使用 `classList.toggle()` 简化条件判断
|
|
|
-5. 添加移动端交互时,注意检查窗口宽度(`window.innerWidth`)以区分设备类型
|
|
|
|
|
-6. 使用 `e.stopPropagation()` 防止事件冒泡,避免触发外部点击事件
|
|
|
|
|
|
|
+5. 添加移动端交互时,注意检查窗口宽度(`window.innerWidth`)以区分设备类型
|
|
|
|
|
+6. 使用 `e.stopPropagation()` 防止事件冒泡,避免触发外部点击事件
|
|
|
|
|
|
|
|
### 修改文档结构
|
|
### 修改文档结构
|
|
|
-1. 编辑 `docs/index.md`
|
|
|
|
|
|
|
+1. 编辑项目根目录的 `index.md`
|
|
|
2. 在对应目录下创建/删除 `.md` 文件
|
|
2. 在对应目录下创建/删除 `.md` 文件
|
|
|
-3. 无需重启服务器,刷新页面即可
|
|
|
|
|
|
|
+3. 无需重启服务器,刷新页面即可(缓存5秒后生效)
|
|
|
|
|
|
|
|
### 修改/扩展编辑功能
|
|
### 修改/扩展编辑功能
|
|
|
-1. 所有文档保存操作必须通过 PUT API,并经过安全验证
|
|
|
|
|
|
|
+1. 所有文档保存操作必须通过 PUT API,并经过安全验证
|
|
|
2. 编辑器光标定位依赖 `findVisibleElement()` 和 `positionCursorByElement()` 函数
|
|
2. 编辑器光标定位依赖 `findVisibleElement()` 和 `positionCursorByElement()` 函数
|
|
|
3. 修改编辑行为时注意保持 `currentMarkdownContent` 和 `savedScrollPosition` 的同步
|
|
3. 修改编辑行为时注意保持 `currentMarkdownContent` 和 `savedScrollPosition` 的同步
|
|
|
4. 编辑模式切换时需要正确管理 DOM 显示/隐藏状态
|
|
4. 编辑模式切换时需要正确管理 DOM 显示/隐藏状态
|
|
|
-5. 不要允许编辑功能创建新文件,只能编辑已存在的文档
|
|
|
|
|
|
|
+5. 不要允许编辑功能创建新文件,只能编辑已存在的文档
|
|
|
|
|
|
|
|
## 安全注意事项
|
|
## 安全注意事项
|
|
|
|
|
|
|
|
-**路径遍历防护**:
|
|
|
|
|
|
|
+**路径遍历防护**:
|
|
|
- `sanitizePath()` - 移除 `../`、`/`、`\` 等危险字符
|
|
- `sanitizePath()` - 移除 `../`、`/`、`\` 等危险字符
|
|
|
- `validatePath()` - 确保解析后的路径在 `docs/` 目录内
|
|
- `validatePath()` - 确保解析后的路径在 `docs/` 目录内
|
|
|
- 所有 API 都必须使用这两个函数验证用户输入
|
|
- 所有 API 都必须使用这两个函数验证用户输入
|
|
|
|
|
|
|
|
-**示例**:
|
|
|
|
|
|
|
+**示例**:
|
|
|
```javascript
|
|
```javascript
|
|
|
const category = sanitizePath(req.params.category);
|
|
const category = sanitizePath(req.params.category);
|
|
|
const docPath = path.join(docsDir, category, `${docName}.md`);
|
|
const docPath = path.join(docsDir, category, `${docName}.md`);
|
|
@@ -239,50 +239,50 @@ if (!validatePath(docPath, docsDir)) {
|
|
|
## 响应式设计要点
|
|
## 响应式设计要点
|
|
|
|
|
|
|
|
### 移动端适配 (≤768px)
|
|
### 移动端适配 (≤768px)
|
|
|
-- 左右侧边栏默认折叠,通过底部悬浮按钮切换
|
|
|
|
|
|
|
+- 左右侧边栏默认折叠,通过底部悬浮按钮切换
|
|
|
- 侧边栏以 `fixed` 定位覆盖在内容区上方
|
|
- 侧边栏以 `fixed` 定位覆盖在内容区上方
|
|
|
- 使用 `transform: translateX()` 实现滑入滑出动画
|
|
- 使用 `transform: translateX()` 实现滑入滑出动画
|
|
|
-- 回到顶部按钮位置调整为 `bottom: 100px`,避免与侧边栏按钮冲突
|
|
|
|
|
|
|
+- 回到顶部按钮位置调整为 `bottom: 100px`,避免与侧边栏按钮冲突
|
|
|
|
|
|
|
|
### 平板适配 (768px-1024px)
|
|
### 平板适配 (768px-1024px)
|
|
|
-- 左侧边栏默认展开,右侧边栏默认折叠
|
|
|
|
|
-- 右侧边栏以 `fixed` 定位,只在需要时显示
|
|
|
|
|
|
|
+- 左侧边栏默认展开,右侧边栏默认折叠
|
|
|
|
|
+- 右侧边栏以 `fixed` 定位,只在需要时显示
|
|
|
|
|
|
|
|
### 桌面端 (>1024px)
|
|
### 桌面端 (>1024px)
|
|
|
- 左右侧边栏始终展开
|
|
- 左右侧边栏始终展开
|
|
|
-- 三栏布局:文档导航 + 内容区 + TOC 目录
|
|
|
|
|
|
|
+- 三栏布局:文档导航 + 内容区 + TOC 目录
|
|
|
|
|
|
|
|
## 常见问题
|
|
## 常见问题
|
|
|
|
|
|
|
|
### 文档显示为空或 404
|
|
### 文档显示为空或 404
|
|
|
-检查:
|
|
|
|
|
-1. `docs/index.md` 中是否有对应条目
|
|
|
|
|
-2. 文件名是否与 `index.md` 中的名称完全一致(区分大小写)
|
|
|
|
|
|
|
+检查:
|
|
|
|
|
+1. 项目根目录的 `index.md` 中是否有对应条目
|
|
|
|
|
+2. 文件名是否与 `index.md` 中的名称完全一致(区分大小写)
|
|
|
3. 文件是否在正确的分类目录下
|
|
3. 文件是否在正确的分类目录下
|
|
|
|
|
|
|
|
### 搜索功能不工作
|
|
### 搜索功能不工作
|
|
|
-检查:
|
|
|
|
|
|
|
+检查:
|
|
|
1. 搜索关键词是否至少 2 个字符
|
|
1. 搜索关键词是否至少 2 个字符
|
|
|
2. 文档内容是否包含匹配文本
|
|
2. 文档内容是否包含匹配文本
|
|
|
3. 浏览器控制台是否有 API 错误
|
|
3. 浏览器控制台是否有 API 错误
|
|
|
|
|
|
|
|
### 移动端侧边栏无法关闭
|
|
### 移动端侧边栏无法关闭
|
|
|
-检查:
|
|
|
|
|
|
|
+检查:
|
|
|
1. 点击事件是否正确绑定到 document
|
|
1. 点击事件是否正确绑定到 document
|
|
|
2. `e.stopPropagation()` 是否正确阻止了按钮点击事件冒泡
|
|
2. `e.stopPropagation()` 是否正确阻止了按钮点击事件冒泡
|
|
|
-3. 窗口宽度判断逻辑是否正确(`window.innerWidth <= 1024`)
|
|
|
|
|
|
|
+3. 窗口宽度判断逻辑是否正确(`window.innerWidth <= 1024`)
|
|
|
|
|
|
|
|
### 性能问题
|
|
### 性能问题
|
|
|
-检查:
|
|
|
|
|
-1. 是否为每个元素单独绑定了事件(应使用事件委托)
|
|
|
|
|
-2. 是否频繁查询 DOM(应使用 `DOM` 缓存对象)
|
|
|
|
|
|
|
+检查:
|
|
|
|
|
+1. 是否为每个元素单独绑定了事件(应使用事件委托)
|
|
|
|
|
+2. 是否频繁查询 DOM(应使用 `DOM` 缓存对象)
|
|
|
3. 是否对搜索等高频操作使用了防抖
|
|
3. 是否对搜索等高频操作使用了防抖
|
|
|
|
|
|
|
|
### 编辑功能无法保存
|
|
### 编辑功能无法保存
|
|
|
-检查:
|
|
|
|
|
-1. 文件是否存在(编辑功能不能创建新文件)
|
|
|
|
|
|
|
+检查:
|
|
|
|
|
+1. 文件是否存在(编辑功能不能创建新文件)
|
|
|
2. 浏览器控制台是否有 PUT API 错误
|
|
2. 浏览器控制台是否有 PUT API 错误
|
|
|
-3. 服务器是否返回 403(路径验证失败)或 400(数据格式错误)
|
|
|
|
|
|
|
+3. 服务器是否返回 403(路径验证失败)或 400(数据格式错误)
|
|
|
4. 文件权限是否允许服务器写入
|
|
4. 文件权限是否允许服务器写入
|
|
|
|
|
|
|
|
## 技术栈版本
|
|
## 技术栈版本
|
|
@@ -291,4 +291,4 @@ if (!validatePath(docPath, docsDir)) {
|
|
|
- Express: 4.x
|
|
- Express: 4.x
|
|
|
- Marked.js: 11.x
|
|
- Marked.js: 11.x
|
|
|
- Highlight.js: 11.x
|
|
- Highlight.js: 11.x
|
|
|
-- 前端:Vanilla JavaScript (ES6+),无框架依赖
|
|
|
|
|
|
|
+- 前端:Vanilla JavaScript (ES6+),无框架依赖
|