# underline-action

> ## 这是什么

Latest version **2.4.15-beta.3** (published 2026-05-11) · 0 weekly downloads

## Install

```sh
npm install underline-action
pnpm add underline-action
yarn add underline-action
bun add underline-action
```

## Health

**Score 50/100 (C)** — status: active.

Positive: has types; no vulnerabilities.

Warnings: low downloads; no esm support.

## Facts

| | |
|---|---|
| Version | 2.4.15-beta.3 |
| Published | 2026-05-11 |
| First published | 2022-10-12 |
| Weekly downloads | 0 |
| TypeScript types | bundled |
| Module format | CommonJS |
| Dependencies | 1 |
| Unpacked size | 1.2 MB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 2 |
| Maintainers | yubiao_li |

## Links

- npm: https://www.npmjs.com/package/underline-action
- Repository: https://github.com/Yubiao-Li/underline-action
- Homepage: https://github.com/Yubiao-Li/underline-action#readme
- Issues: https://github.com/Yubiao-Li/underline-action/issues
- npm.io page: https://npm.io/package/underline-action

## Dependencies (1)

- [@vue/runtime-core](https://npm.io/package/@vue/runtime-core.md) ^3.3.4

## Recent versions

- 2.4.15-beta.3 (latest) — 2026-05-11
- 2.4.15-beta.2 — 2026-05-11
- 2.4.15-beta.1 — 2026-04-23
- 2.4.15-beta.0 — 2026-04-23
- 2.4.14 — 2026-03-23
- 2.4.13 — 2026-03-19
- 2.4.12-beta.12 — 2025-11-10
- 2.4.12-beta.11 — 2025-10-28
- 2.4.12-beta.10 — 2025-09-23
- 2.4.12-beta.9 — 2025-05-22
- 2.4.12-beta.8 — 2025-05-14
- 2.4.12-beta.7 — 2025-05-09
- 2.4.12-beta.6 — 2025-05-08
- 2.4.12-beta.5 — 2025-05-08
- 2.4.12-beta.4 — 2025-05-08
- … 155 more at https://npm.io/package/underline-action/versions

## README

# Underline-action

## 这是什么

该库用于选中页面一段富文本并给文本划线，常用于各种划线评论与划线高亮场景

## install

`npm i underline-action`

## How to use

```js
import { UnderlineAction } from 'underline-action';

// 初始化
const action = UnderlineAction({
  selector: '#app', // 需要插入划线的祖先dom
  tag: 'span',  // 插入的标签类型
  getKeyByRange({ start, end, props }) {  // 生成划线id的规则
    return `${start}-${end}`;
  },
  needFilterNode(node) {  // 需要过滤的节点
    if (xxx) {
      return NodeFilter.FILTER_REJECT;
    }

    return NodeFilter.FILTER_ACCEPT;
  },
  getAttachNode(node) { // 不计入总字数的节点，但是如果被跨过会被划线，返回true，目前仅支持文本节点
    if (node.parentElement.tagName === 'SUP') {
      return true;
    }
  },
  getRenderInfo(node) {   // 获取节点的用于渲染的信息，会在render方法的patchProps带上
    return {};
  }
});

// 划线
const key = action.insertSpanInRange(start, end, props, temp)
# start 开始划线的位置
# end 结束划线的位置
# props span上要带的属性
# temp boolean 为true返回生成的span数组，为false会存在实例的state里面，这里如果不需要存储状态建议用true

// 用key删除划线
action.removeSpanByKey(key)
# key 划线id

// 直接用span删除划线
action.mergeTextNode(span)
# span 划线span

// 获取起止之间文本
action.getTextByStartEnd(start, end)
# start 开始的位置
# end 结束的位置

// 获取所有span
const spans = action.getSpanByKey(key)
# key 划线id

// 获取dom总字数
const num = action.getTotalCount()

// 获取用于渲染元信息
const renderInfo = action.getRenderInfoByStartEnd(start, end)

// 使用元信息渲染，参考vue调和器
render(renderInfos, renderdom, {
  patchProp(el, key, prevValue, nextValue) {
    switch (key) {
      case 'textContent':
      case 'style':
        el[key] = nextValue;
        break;
      case 'type':
        break;
      default:
        el.setAttribute(key, nextValue);
        break;
    }
  },
  remove(el) {
    el.remove();
  },
  createElement(type) {
    return document.createElement(type);
  },
  createText(text) {
    return document.createTextNode(text);
  },
  insert(node, parent, anchor) {
    if (anchor) {
      parent.insertBefore(node, anchor);
    } else {
      parent.appendChild(node);
    }
  },
});
```

---
_Source: https://npm.io/package/underline-action · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
