# Markdown-it Sticky Table Plugin

一个 markdown-it 插件，用于实现表格的固定头部、固定列和横向滚动功能。

## 功能特性

1. **固定表格头部**: 滚动时表头始终保持可见
2. **固定前N行**: 支持固定前N行数据（不仅限于表头）
3. **固定前N列**: 支持固定前N列数据，水平滚动时保持可见
4. **交叉固定**: 同时支持固定行和列的交叉区域显示
5. **横向滚动**: 当表格内容超出屏幕宽度时，可以左右滑动浏览
6. **美观样式**: 包含hover效果和自定义滚动条样式
7. **性能优化**: CSS样式缓存机制，提升渲染性能
8. **错误处理**: 完善的参数验证和错误提示
9. **可配置选项**: 支持自定义最大高度、样式类名、固定行数和列数等

## 构建和测试

### 构建项目

```bash
# 构建生产版本（生成 CommonJS 和 ES Module 两种格式）
npm run build

# 开发模式（监听文件变化）
npm run dev
```

### 运行测试

```bash
# 测试 CommonJS/UMD 版本
npm test

# 测试 ES Module 版本
npm run test:esm

# 运行所有测试
npm run test:all
```

### 生成测试html

```bash
node test/test-sticky-rows.js
```

## 使用方法

### CommonJS/Node.js

```javascript
const MarkdownIt = require('markdown-it');
const stickyTablePlugin = require('markdown-it-sticky-table');

const md = new MarkdownIt();
md.use(stickyTablePlugin);
```

### ES Module/Modern JavaScript

```javascript
import MarkdownIt from 'markdown-it';
import stickyTablePlugin from 'markdown-it-sticky-table';

const md = new MarkdownIt();
md.use(stickyTablePlugin);
```

### 浏览器 (UMD)

```html
<script src="https://cdn.jsdelivr.net/npm/markdown-it/dist/markdown-it.min.js"></script>
<script src="path/to/markdown-it-sticky-table.js"></script>

<script>
const md = window.markdownit();
md.use(window.markdownItStickyTable);
</script>
```

### 基本用法

```javascript
const MarkdownIt = require('markdown-it');
const stickyTablePlugin = require('./src/index');

const md = new MarkdownIt();
md.use(stickyTablePlugin);

const markdown = `
| 姓名 | 年龄 | 城市 |
|------|------|------|
| 张三 | 25   | 北京 |
| 李四 | 30   | 上海 |
`;

const html = md.render(markdown);
```

### 配置选项

```javascript
md.use(stickyTablePlugin, {
  className: 'custom-table-container',  // 容器CSS类名
  stickyHeader: true,                   // 是否启用固定头部（向后兼容）
  stickyRows: 3,                       // 固定前N行
  stickyColumns: 2,                    // 固定前N列（新功能）
  horizontalScroll: true,               // 是否启用横向滚动
  maxHeight: '400px'                    // 表格最大高度
});
```

### 固定前N行示例

```javascript
// 只固定表头（默认行为）
md.use(stickyTablePlugin, {
  stickyRows: 1
});

// 固定前3行（表头+前2行数据）
md.use(stickyTablePlugin, {
  stickyRows: 3,
  maxHeight: '300px'
});

// 不固定任何行
md.use(stickyTablePlugin, {
  stickyRows: 0
});
```

### 固定前N列示例

```javascript
// 固定前1列（适用于有ID列的表格）
md.use(stickyTablePlugin, {
  stickyColumns: 1
});

// 固定前2列（适用于有多个标识列的表格）
md.use(stickyTablePlugin, {
  stickyColumns: 2,
  maxHeight: '400px'
});

// 同时固定前2行和前2列
md.use(stickyTablePlugin, {
  stickyRows: 2,
  stickyColumns: 2,
  maxHeight: '400px'
});

// 不固定任何列
md.use(stickyTablePlugin, {
  stickyColumns: 0
});
```

## 选项说明

| 选项 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `className` | String | `'sticky-table-container'` | 表格容器的CSS类名 |
| `stickyHeader` | Boolean | `true` | 是否启用固定表头功能（向后兼容） |
| `stickyRows` | Number | `1` | 固定前N行数据，0表示不固定任何行 |
| `stickyColumns` | Number | `0` | 固定前N列数据，0表示不固定任何列 |
| `horizontalScroll` | Boolean | `true` | 是否启用横向滚动 |
| `maxHeight` | String | `'400px'` | 表格的最大高度，可设为null禁用 |

### 参数详细说明

- **stickyRows**:
  - 设置为 `1` 时，只固定表头
  - 设置为 `3` 时，固定表头和前2行数据
  - 设置为 `0` 时，不固定任何行
  - 每个固定行都有独特的z-index和背景色

- **stickyColumns**:
  - 设置为 `1` 时，只固定第一列
  - 设置为 `2` 时，固定前两列
  - 设置为 `0` 时，不固定任何列
  - 每个固定列默认宽度为150px，有独特的z-index和背景色
  - 固定列与固定行的交叉区域会自动处理层级和样式

- **交叉固定效果**:
  - 同时启用固定行和列时，交叉区域会自动处理
  - 交叉区域的z-index高于单独的行或列
  - 保证固定行在垂直滚动时正常工作，固定列在水平滚动时正常工作

- **向后兼容性**:
  - 当 `stickyHeader: false` 且未设置 `stickyRows` 时，自动设为 `stickyRows: 0`
  - 新增的 `stickyColumns` 参数默认为 0，不影响现有功能
  - 保持与旧版本的完全兼容

## 测试

运行测试脚本：

```bash
npm test
```

这将生成一个HTML文件 `test/output.html`，在浏览器中打开可以测试插件功能。

## 构建

开发模式（监听文件变化）：

```bash
npm run dev
```

生产构建：

```bash
npm run build
```

## 生成的HTML结构

插件会将原始的markdown表格转换为以下HTML结构：

```html
<div class="sticky-table-container" style="max-height: 400px; overflow-y: auto; overflow-x: auto; position: relative;">
  <table class="sticky-table">
    <thead class="sticky-header">
      <tr class="sticky-row sticky-row-0">
        <th>列1</th>
        <th>列2</th>
      </tr>
    </thead>
    <tbody>
      <tr class="sticky-row sticky-row-1">
        <td>第1行数据</td>
        <td>第1行数据</td>
      </tr>
      <tr class="sticky-row sticky-row-2">
        <td>第2行数据</td>
        <td>第2行数据</td>
      </tr>
      <tr>
        <td>普通行</td>
        <td>普通行</td>
      </tr>
    </tbody>
  </table>
</div>
<style>
  /* CSS样式会自动插入，包含固定行的样式 */
</style>
```

### CSS类说明

- `sticky-table-container`: 表格容器
- `sticky-table`: 表格本体
- `sticky-header`: 表头固定样式
- `sticky-row`: 固定行通用样式
- `sticky-row-0`, `sticky-row-1`, etc.: 每个固定行的特定样式
- `sticky-column`: 固定列通用样式
- `sticky-column-0`, `sticky-column-1`, etc.: 每个固定列的特定样式

## CSS样式特性

- **固定表头**: 使用 `position: sticky` 实现
- **固定多行**: 支持固定前N行，每行有不同的top值和z-index
- **固定多列**: 支持固定前N列，每列有不同的left值和z-index
- **交叉固定**: 固定行和列的交叉区域自动处理层级和样式
- **横向滚动**: 容器设置 `overflow-x: auto`
- **美观滚动条**: 自定义webkit和Firefox滚动条样式
- **悬停效果**: 表格行和固定列的hover效果，交叉区域有特殊的hover样式
- **层级管理**: 自动管理固定行、列和交叉区域的z-index，确保正确的显示层级
- **性能优化**: CSS样式缓存机制，避免重复生成
- **响应式设计**: 适配不同屏幕尺寸

## 浏览器兼容性

- Chrome/Safari: 完全支持
- Firefox: 完全支持  
- Edge: 完全支持
- IE11: 部分支持（sticky定位可能不工作）

## 许可证

MIT License
