bricks/docs/cn/markdown_viewer.md
2025-10-12 17:59:59 +08:00

250 lines
7.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Bricks Markdown 组件技术文档
> **项目依赖说明**:本组件基于 [marked.js](https://github.com/markedjs/marked) 实现 Markdown 渲染功能。在使用 `bricks.js` 前,需确保已引入 `marked.min.js`。
```html
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
```
---
## 模块概述
`bricks.MdWidget``bricks.MarkdownViewer` 是 Bricks 框架中用于渲染和交互式浏览 Markdown 内容的两个核心组件:
- `MdWidget`:基础 Markdown 显示控件,支持本地文本或远程 URL 加载。
- `MarkdownViewer`:增强型 Markdown 浏览器,内置导航栈(前进/后退)功能,适合构建文档阅读器类应用。
---
## 1. `bricks.MdWidget`
### 类定义
```js
class MdWidget extends bricks.JsWidget
```
### 功能描述
一个轻量级的 Markdown 渲染控件,可从字符串 (`mdtext`) 或远程 URL (`md_url`) 加载内容,并使用 `marked.js` 进行解析渲染。支持动态更新内容和链接拦截处理。
### 构造函数参数:`options`
| 参数 | 类型 | 必填 | 描述 |
|------|------|------|------|
| `mdtext` | String | 否 | 要渲染的 Markdown 文本内容 |
| `md_url` | String | 否 | 远程 Markdown 文件 URL |
| `method` | String | 否(默认 `"GET"` | 请求方式(目前仅支持 GET |
| `params` | Object | 否 | 请求参数(暂未实际用于 GET 请求) |
> ⚠️ 注意:若同时提供 `mdtext` 和 `md_url`,优先使用 `mdtext` 并立即渲染。
### 方法列表
#### `constructor(options)`
初始化组件:
- 若提供了 `mdtext`,则直接调用 `_build1()` 渲染。
- 否则延迟加载 `md_url` 内容,并绑定滚动监听。
#### `set_content(content)`
动态设置 Markdown 内容并重新渲染。
- **参数**
- `content`: (String) 新的 Markdown 字符串
#### `show_scroll(event)`
滚动事件回调,输出当前 `window.scrollY` 到调试日志(通过 `bricks.debug`)。
#### `async build()`
异步加载并渲染来自 `opts.md_url` 的 Markdown 内容。若未指定 URL则不执行任何操作。
#### `async _build(md_url)`
私有方法:通过 `bricks.tget(md_url)` 获取远程 Markdown 内容并渲染。
- 触发事件:`loaded`,携带 `{ url: md_url }`
- 自动重写页面内所有 `<a>` 标签为内部跳转行为
#### `_build1()`
将当前 `this.md_content` 使用 `marked.parse()` 解析为 HTML并插入 DOM。
同时劫持所有链接点击事件,实现内部导航。
> 所有 `<a href="...">` 被改为 `href="#"`,并绑定 `onclick` 调用 `_build(原URL)`。
#### `getname()`
返回控件名称:
- 若设置了 `this.name`,返回该值;
- 否则返回 `'mdtext'`
#### `getValue()`
获取当前控件的值,格式为对象:
```js
{ [name]: md_content }
```
常用于表单数据收集。
#### `setValue(v)`
设置 Markdown 内容(仅赋值,不触发渲染)。通常配合其他逻辑调用。
---
## 2. `bricks.MarkdownViewer`
### 类定义
```js
class MarkdownViewer extends bricks.VBox
```
### 功能描述
一个容器式 Markdown 浏览器,继承自 `VBox`,支持以下特性:
- 可选的“返回”按钮(导航栈)
- 支持点击 Markdown 中的链接进行页面跳转
- 记录访问历史back_stack支持回退至上一页
### 构造函数参数:`options`
| 参数 | 类型 | 必填 | 描述 |
|------|------|------|------|
| `navigator` | Boolean | 否(默认 `true` | 是否显示返回按钮 |
| `recommentable` | Boolean | 否 | (预留字段,当前未使用) |
| `md_url` | String | 否 | 初始加载的远程 Markdown URL |
| `mdtext` | String | 否 | 初始本地 Markdown 文本 |
| `method` | String | 否(默认 `"GET"` | HTTP 方法 |
| `params` | Object | 否 | 请求参数对象 |
> ✅ 提示:使用 `absurl()` 处理相对路径,确保 URL 正确解析。
### 方法列表
#### `constructor(options)`
初始化组件:
- 创建内部 `MdWidget` 实例负责渲染
- 注册 `loaded` 事件以维护导航栈
- 设置样式:自动滚动、占满父容器高度
#### `show_scroll(event)`
`MdWidget`,打印当前滚动位置。
#### `async createBackButton()`
动态创建顶部返回按钮HBox + Text 组合):
- 显示文本 `"<<<<<<<"`
- 点击触发 `go_back()`
- 使用 `widgetBuild` 异步生成 UI 元素(调试信息较多)
> 🛠️ 当前 UI 较原始,未来可替换为图标或更美观样式。
#### `add_back_stack(event)`
当新页面加载完成时,将当前 URL 推入 `back_stack` 数组。
- **事件参数**`event.params.url` 表示刚加载的 URL
#### `async go_back(event)`
实现“返回上一页”逻辑:
1. 弹出当前页 URL
2. 再弹出上一页 URL
3. 使用 `mdtext._build(url)` 加载上一页内容
> 🔒 若栈长度小于 2则禁止返回。
#### `async build()` / `async _build(md_url)`
> ❗注意:此处存在代码冗余 —— `_build` 方法在 `MarkdownViewer` 中重复定义但未被调用(应调用的是 `mdtext._build`)。
建议移除该方法或修正逻辑,避免混淆。
---
## 事件系统
### 自定义事件
| 事件名 | 触发时机 | 携带参数 |
|--------|----------|---------|
| `loaded` | Markdown 内容成功加载并渲染后 | `{ url: string }` |
| `scroll` | 容器发生滚动时(绑定到 DOM | 原生 Event 对象 |
可通过 `.bind('event', handler)` 监听。
---
## 工厂注册
```js
bricks.Factory.register('MarkdownViewer', bricks.MarkdownViewer);
bricks.Factory.register('MdWidget', bricks.MdWidget);
```
允许通过 JSON 描述符动态创建组件:
### 示例 JSON 配置
```json
{
"widgettype": "MarkdownViewer",
"options": {
"md_url": "/docs/intro.md",
"navigator": true
}
}
```
---
## 使用示例
### 示例 1直接渲染本地 Markdown
```js
const mdWidget = new bricks.MdWidget({
mdtext: "# Hello\nWelcome to Bricks Markdown Viewer!"
});
document.body.appendChild(mdWidget.dom_element);
```
### 示例 2加载远程 Markdown 并启用导航
```js
const viewer = new bricks.MarkdownViewer({
md_url: 'https://example.com/README.md',
navigator: true
});
document.body.appendChild(viewer.dom_element);
```
### 示例 3动态更新内容
```js
mdWidget.set_content("## New Content\nUpdated at " + new Date().toLocaleString());
```
---
## 注意事项 & 建议
1. **依赖必须提前加载**
```html
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
```
2. **安全性提示**
- `innerHTML = marked.parse(...)` 存在 XSS 风险
- 如需展示用户输入,请先对 HTML 输出做净化处理(如使用 DOMPurify
3. **性能优化建议**
- 避免频繁调用 `set_content` 或 `_build`
- 对大型文档考虑分页或懒加载
4. **代码改进建议**
- `MarkdownViewer._build` 方法冗余且可能错误,建议删除或重构
- `createBackButton` 应支持国际化或自定义文本
- 链接拦截逻辑可抽象成独立方法便于复用
---
## 版本信息
- **作者**Bricks Framework 团队
- **依赖库**[marked@latest](https://marked.js.org/)
- **兼容性**现代浏览器ES6+ 支持)
---
📌 **文档版本**v1.0
📅 **最后更新**2025年4月5日