Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

nowclipboard

Package Overview
Dependencies
Maintainers
1
Versions
11
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

nowclipboard

现代剪贴板工具库 - 零依赖,支持浏览器和 Node.js 双环境

latest
Source
npmnpm
Version
1.1.9
Version published
Weekly downloads
15
36.36%
Maintainers
1
Weekly downloads
 
Created
Source

NowClipboard

中文 | English

现代剪贴板工具库 -- 零依赖,支持浏览器和 Node.js 双环境。

特性

  • 现代 API 优先 -- 优先使用 navigator.clipboard.writeText(),自动降级到 document.execCommand
  • Promise 异步 -- 所有操作返回 Promise,支持 async/await
  • 自动重试 -- 内置可配置的指数退避重试机制,支持超时控制和 AbortSignal 取消
  • 双环境支持 -- 浏览器 + Node.js(Windows PowerShell / macOS pbcopy / Linux xclip/xsel
  • 读写双向 -- 支持写入(复制/剪切)和读取(粘贴)剪贴板
  • 富内容读取 -- readRich() 读取剪贴板中的文本、HTML 和图片
  • 粘贴监听 -- 通过 onPaste 监听粘贴事件,自动解析文本、HTML、文件
  • 变更监听 -- 通过 onChange 轮询监听剪贴板内容变化
  • 权限检测 -- 通过 queryPermission 查询剪贴板读写权限状态
  • HTML 属性绑定 -- 通过 data-nc-* 属性声明式绑定复制行为
  • 事件委托 -- 支持选择器字符串、Element、NodeList 三种触发方式
  • 资源安全 -- 完善的 destroy() 方法防止内存泄漏,destroy 后调用方法会抛错
  • 图片复制 -- 支持 Blob、File、HTMLImageElement、HTMLCanvasElement、URL 等多种图片源
  • 富文本复制 -- 同时复制 HTML + 纯文本,自动降级到 execCommand
  • Node.js 写入 -- write() / writeImage() 在 Node.js 中写入文本和图片到系统剪贴板
  • 多格式写入 -- writeFormats() 一次写入多种 MIME 类型
  • 剪贴板历史 -- History 类自动记录剪贴板变更,支持搜索和持久化
  • 跨标签页同步 -- onSync() 基于 BroadcastChannel 自动同步复制操作
  • iOS Safari 适配 -- 针对移动端 Safari 的特殊降级处理
  • data URL 优化 -- data: URL 直接解码为 Blob,不走 fetch 网络请求
  • TypeScript -- 内置完整的 .d.ts 类型定义
  • ESM 支持 -- 提供 ESM 模块版本,支持 import 语法和 Tree-shaking
  • 零依赖 -- 单文件,无任何外部依赖

文件说明

文件说明
NowClipboard.js完整版(带注释,便于阅读和调试)
NowClipboard.min.js压缩版(生产环境推荐)
NowClipboard.esm.mjsESM 模块版本(支持 import 语法)
NowClipboard.d.tsTypeScript 类型定义文件
demo.html交互式演示页面

安装

npm install nowclipboard --save

快速开始

浏览器引入

<!-- 开发环境 -->
<script src="NowClipboard.js"></script>

<!-- 生产环境(推荐) -->
<script src="NowClipboard.min.js"></script>

Node.js 引入

var NowClipboard = require('nowclipboard');

AMD 引入

require(['NowClipboard'], function (NowClipboard) {
  // ...
});

ESM 引入

// 默认导入
import NowClipboard from 'nowclipboard';

// 命名导入(按需引入)
import { copy, read, readRich, copyImage, copyRich, onChange, write, writeImage, writeFormats, onSync, History } from 'nowclipboard';

使用方式

1. HTML 属性绑定(声明式)

通过 data-nc-* 属性指定复制行为,无需写额外 JS 逻辑:

<!-- 复制指定文本 -->
<button class="btn" data-nc-text="要复制的内容">复制文本</button>

<!-- 复制目标元素的内容 -->
<input id="source" value="输入框内容">
<button class="btn" data-nc-target="#source">复制输入框</button>

<!-- 剪切目标元素的内容 -->
<textarea id="content">可编辑内容</textarea>
<button class="btn" data-nc-target="#content" data-nc-action="cut">剪切</button>
<script src="NowClipboard.js"></script>
<script>
  var clipboard = new NowClipboard('.btn');

  clipboard.on('success', function (e) {
    console.log('复制成功:', e.text);
    e.clearSelection();
  });

  clipboard.on('error', function (e) {
    console.error('复制失败:', e.error);
  });
</script>

2. 配置项初始化(编程式)

通过函数动态控制复制行为:

var clipboard = new NowClipboard('.btn', {
  // 自定义操作类型
  action: function (trigger) {
    return trigger.getAttribute('data-action') || 'copy';
  },

  // 自定义目标元素
  target: function (trigger) {
    var id = trigger.getAttribute('data-target');
    return document.getElementById(id);
  },

  // 自定义复制文本
  text: function (trigger) {
    return '当前时间: ' + new Date().toLocaleString();
  },

  // 容器元素(用于降级方案中的临时元素挂载)
  container: document.body,

  // 重试配置
  retries: 3,        // 最大重试次数(默认 2)
  retryDelay: 200,   // 基础延迟 ms(默认 100,指数退避)
  timeout: 5000,     // 超时 ms(默认 0,不超时)

  // AbortSignal 取消操作
  signal: abortController.signal
});

3. 静态方法(直接调用)

不需要实例化,直接复制文本:

// 复制文本
NowClipboard.copy('Hello World')
  .then(function (text) {
    console.log('已复制:', text);
  })
  .catch(function (err) {
    console.error('失败:', err.message);
  });

// 使用 AbortSignal 取消操作
var controller = new AbortController();
NowClipboard.copy('Hello World', { signal: controller.signal });

// 1 秒后取消
setTimeout(function () { controller.abort(); }, 1000);

// async/await 写法
async function doCopy() {
  try {
    var text = await NowClipboard.copy('Hello World');
    console.log('已复制:', text);
  } catch (err) {
    console.error('失败:', err.message);
  }
}

4. 静态剪切

var textarea = document.querySelector('#myTextarea');

NowClipboard.cut(textarea).then(function (text) {
  console.log('已剪切:', text);
});

// 带重试配置
NowClipboard.cut(textarea, { retries: 3, timeout: 5000 }).then(function (text) {
  console.log('已剪切:', text);
});

5. 读取剪贴板

// 浏览器(需要 HTTPS + 用户授权)
NowClipboard.read().then(function (text) {
  console.log('剪贴板内容:', text);
});

// 带配置
NowClipboard.read({ retries: 3, timeout: 3000 }).then(function (text) {
  console.log('读取成功:', text);
});

6. 读取剪贴板富内容

读取剪贴板中的纯文本、HTML 和图片。需要 HTTPS + 支持 clipboard.read() API 的现代浏览器。

NowClipboard.readRich().then(function (result) {
  console.log('纯文本:', result.text);
  console.log('HTML:', result.html);
  console.log('图片数量:', result.images.length);
});

// 带重试和超时配置
NowClipboard.readRich({ retries: 3, timeout: 5000 });

7. 粘贴事件监听

// 监听整个页面的粘贴事件
var listener = NowClipboard.onPaste(null, function (data) {
  console.log('文本:', data.text);
  console.log('HTML:', data.html);
  console.log('文件:', data.files);
  // data.originalEvent 为原始 paste 事件
});

// 监听指定选择器(事件委托)
var listener2 = NowClipboard.onPaste('.paste-area', function (data) {
  console.log('粘贴到目标区域:', data.text);
});

// 销毁监听
listener.destroy();

8. 剪贴板变更监听

轮询检测剪贴板内容变化,当内容改变时触发回调。

var watcher = NowClipboard.onChange(function (data) {
  console.log('剪贴板内容变更:', data.text);
}, 1000); // 轮询间隔 1000ms(默认)

// 销毁监听
watcher.destroy();

⚠️ onChange 使用轮询方式读取剪贴板,浏览器中需要页面获焦且有读取权限。频繁轮询可能在某些浏览器触发权限弹窗。

9. 权限检测

// 检测读取权限
NowClipboard.queryPermission('read').then(function (result) {
  console.log('读取权限:', result.state); // 'granted', 'denied', 或 'prompt'
});

// 检测写入权限
NowClipboard.queryPermission('write').then(function (result) {
  console.log('写入权限:', result.state);
});

10. 复制图片

需要 HTTPS + 现代浏览器(支持 ClipboardItem API)。

// 复制图片 URL
NowClipboard.copyImage('https://example.com/photo.png')
  .then(function (blob) {
    console.log('图片已复制,大小:', blob.size);
  });

// 复制 data: URL(不走网络请求,直接解码为 Blob)
NowClipboard.copyImage('data:image/png;base64,...');

// 复制 Canvas 画布
var canvas = document.querySelector('#myCanvas');
NowClipboard.copyImage(canvas);

// 复制 img 元素
var img = document.querySelector('#myImage');
NowClipboard.copyImage(img);

// 复制任意 Blob
var blob = new Blob([data], { type: 'image/png' });
NowClipboard.copyBlob(blob);

11. 复制富文本

同时复制 HTML 和纯文本,粘贴时保留格式。

NowClipboard.copyRich({
  text: '纯文本内容',
  html: '<b>加粗</b>的 <em>富文本</em> 内容'
}).then(function (result) {
  console.log('已复制:', result.text, result.html);
});

// 支持 AbortSignal
var controller = new AbortController();
NowClipboard.copyRich({
  text: '纯文本',
  html: '<b>富文本</b>',
  signal: controller.signal
});

通过 HTML 属性绑定富文本复制:

<div id="rich-content">
  <h3>标题</h3>
  <p>这是 <strong>加粗</strong> 的内容</p>
</div>
<button class="btn" data-nc-target="#rich-content" data-nc-html="true">
  复制富文本
</button>

12. Node.js 环境

var NowClipboard = require('./NowClipboard.js');

NowClipboard.copy('从服务端复制的内容').then(function (text) {
  console.log('已写入系统剪贴板:', text);
}).catch(function (err) {
  console.error('失败:', err.message);
});

// 读取系统剪贴板
NowClipboard.read().then(function (text) {
  console.log('剪贴板内容:', text);
});

Node.js 系统命令依赖:

操作系统写入命令读取命令备注
Windowspowershell -EncodedCommandpowershell -EncodedCommand使用 Base64 编码传递文本,避免 Unicode 编码问题
macOSpbcopypbpaste系统内置
Linuxxclipxclip -o需安装:sudo apt install xclip
Linux (降级)xselxsel -o备选:sudo apt install xsel

13. 写入文本(write)

write()copy() 的别名,在浏览器和 Node.js 中均可使用。语义上更强调"写入"操作。

// 浏览器和 Node.js 通用
NowClipboard.write('写入剪贴板的文本').then(function (text) {
  console.log('已写入:', text);
});

14. 写入图片(writeImage)

在浏览器和 Node.js 中均可写入图片到系统剪贴板。

// 浏览器:与 copyImage 相同
NowClipboard.writeImage('https://example.com/photo.png')
  .then(function (blob) { console.log('图片已写入:', blob.size); });

// 浏览器:Canvas / img 元素
NowClipboard.writeImage(document.querySelector('#myCanvas'));

// Node.js:从 Buffer 写入
var fs = require('fs');
var imgBuffer = fs.readFileSync('/path/to/image.png');
NowClipboard.writeImage(imgBuffer).then(function () {
  console.log('图片已写入系统剪贴板');
});

// Node.js:从文件路径写入
NowClipboard.writeImage('/path/to/image.png').then(function () {
  console.log('图片已写入');
});

Node.js writeImage 系统命令:

操作系统命令备注
WindowsPowerShell Clipboard.SetImage()通过 Base64 传递图片数据
macOSpbcopy支持 PNG 格式
Linuxxclip -t image/png需安装 xclip

15. 多格式写入(writeFormats)

一次写入多种 MIME 格式到剪贴板。需要 HTTPS + 现代浏览器(支持 ClipboardItem API)。

// 同时写入纯文本和 HTML
NowClipboard.writeFormats({
  'text/plain': 'Hello World',
  'text/html': '<b>Hello</b> World'
}).then(function (formats) {
  console.log('已写入格式:', Object.keys(formats));
});

// 写入文本 + 图片
NowClipboard.writeFormats({
  'text/plain': '图片描述',
  'image/png': imageBlob
});

// 自定义 MIME 类型
NowClipboard.writeFormats({
  'text/csv': 'name,age\nAlice,30',
  'application/json': '{"name":"Alice","age":30}'
});

16. 剪贴板历史(History)

自动记录剪贴板内容变更,支持搜索和持久化存储。

// 创建历史实例
var history = new NowClipboard.History({
  maxSize: 50,           // 最大条目数(默认 50)
  storage: 'localStorage', // 存储方式:'memory' | 'localStorage' | 'sessionStorage'
  storageKey: 'my_history', // 存储键名(默认 'nowclipboard_history')
  pollInterval: 1000     // 轮询间隔 ms(默认 1000)
});

// 开始监听
history.start();

// 获取所有历史
history.list(); // [{ text: '...', timestamp: 1234567890, type: 'text' }, ...]

// 搜索历史
history.search('关键词'); // 返回匹配的条目

// 获取最近一条
history.latest(); // { text: '...', timestamp: ..., type: 'text' }

// 当前条目数
history.size(); // 5

// 清空历史
history.clear();

// 停止监听(保留历史数据)
history.stop();

// 销毁实例(清空历史 + 停止监听)
history.destroy();

⚠️ History 使用 onChange 轮询监听剪贴板,仅浏览器环境可用。localStorage / sessionStorage 持久化需要页面在 HTTP/HTTPS 下访问。

17. 跨标签页同步(onSync)

基于 BroadcastChannel API,同一来源下的多个标签页自动同步剪贴板操作。

// 启动同步(默认自动同步 copy/cut 操作)
var sync = NowClipboard.onSync({
  channel: 'nowclipboard', // BroadcastChannel 名称(默认 'nowclipboard')
  autoSync: true           // 自动同步 copy/cut(默认 true)
});

// 监听其他标签页的复制操作
sync.addListener(function (data) {
  console.log('其他标签页复制了:', data.type, data.text);
  // data.type: 'copy' | 'cut' | 自定义
  // data.text: 复制的文本
  // data.timestamp: 时间戳
});

// 广播自定义消息
sync.broadcast({ type: 'custom', message: 'Hello from Tab A' });

// 移除监听
sync.removeListener(myCallback);

// 销毁同步实例(恢复原始 copy/cut 方法)
sync.destroy();

⚠️ onSync 仅在浏览器环境且支持 BroadcastChannel 的浏览器中可用(Chrome 54+、Firefox 38+、Safari 15.4+)。不支持时会静默返回空操作对象。

API 参考

构造函数

new NowClipboard(trigger, [options])
参数类型说明
triggerstring | Element | NodeListCSS 选择器、DOM 元素或元素集合
options.actionFunction(trigger) => 'copy' | 'cut'
options.targetFunction(trigger) => Element
options.textFunction(trigger) => string
options.containerElement容器元素,默认 document.body
options.retriesnumber最大重试次数,默认 2
options.retryDelaynumber基础重试延迟 ms,默认 100(指数退避)
options.timeoutnumber超时 ms,默认 0(不超时)
options.signalAbortSignal | null取消操作的信号

实例方法

方法说明
.on(event, handler)注册事件监听(destroy 后调用会抛错)
.once(event, handler)注册一次性事件监听(destroy 后调用会抛错)
.off(event, handler)移除事件监听(destroy 后调用会抛错)
.destroy()销毁实例,移除所有事件监听和 DOM 绑定

静态方法

方法返回值说明
NowClipboard.copy(text, [options])Promise<string>复制文本到剪贴板
NowClipboard.write(text, [options])Promise<string>写入文本到剪贴板(copy 的别名)
NowClipboard.cut(element, [options])Promise<string>剪切元素内容(仅浏览器)
NowClipboard.read([options])Promise<string>读取剪贴板文本
NowClipboard.readRich([options])Promise<{text, html, images}>读取剪贴板富内容(文本+HTML+图片,仅浏览器)
NowClipboard.writeImage(source, [options])Promise<Blob>写入图片到剪贴板(浏览器 + Node.js)
NowClipboard.writeFormats(formats, [options])Promise<FormatsMap>一次写入多种 MIME 格式(仅浏览器)
NowClipboard.copyImage(source, [options])Promise<Blob>复制图片(支持 Blob/File/Img/Canvas/URL)
NowClipboard.copyBlob(blob, [mimeType], [options])Promise<Blob>复制任意 Blob 到剪贴板
NowClipboard.copyRich(options)Promise<{text, html}>复制富文本(HTML + 纯文本)
NowClipboard.onPaste(target, callback){ destroy }监听粘贴事件(仅浏览器)
NowClipboard.onChange(callback, [interval]){ destroy }监听剪贴板变更(仅浏览器,轮询方式)
NowClipboard.onSync([options])SyncInstance跨标签页同步(仅浏览器,BroadcastChannel)
NowClipboard.queryPermission(name)Promise<{ state }>查询剪贴板权限('read'/'write'
NowClipboard.checkSupport([actions])boolean检测环境是否支持剪贴板操作
NowClipboard.HistoryClipboardHistory剪贴板历史类

RetryOptions 配置

选项类型默认值说明
retriesnumber2最大重试次数
retryDelaynumber100基础重试延迟 ms(指数退避)
timeoutnumber0超时 ms(0 = 不超时)
signalAbortSignal | nullnull取消操作的信号

事件

success 事件

复制/剪切操作成功时触发。

clipboard.on('success', function (e) {
  e.action;          // 'copy' 或 'cut'
  e.text;            // 复制的文本内容
  e.trigger;         // 触发操作的 DOM 元素
  e.clearSelection(); // 清除页面选区
});

error 事件

操作失败时触发。

clipboard.on('error', function (e) {
  e.action;          // 'copy' 或 'cut'
  e.trigger;         // 触发操作的 DOM 元素
  e.error;           // Error 对象,包含失败原因
  e.clearSelection(); // 清除页面选区
});

HTML 属性

属性说明示例
data-nc-text指定要复制的文本data-nc-text="复制我"
data-nc-target指定目标元素的 CSS 选择器data-nc-target="#input1"
data-nc-action操作类型:copy(默认)或 cutdata-nc-action="cut"
data-nc-html启用富文本复制模式data-nc-html="true"

降级策略

库会自动按以下顺序尝试最佳方案:

1. navigator.clipboard.writeText()    (HTTPS + 现代浏览器)
       |
       v 失败
2. document.execCommand('copy')       (HTTP + 旧浏览器)
       |
       v 失败
3. child_process (PowerShell/pbcopy/xclip)  (Node.js 环境)
       |
       v 失败
4. 抛出错误,触发 'error' 事件

每层失败后自动重试(默认最多 2 次,指数退避),重试次数、延迟、超时均可配置。支持通过 AbortSignal 取消正在进行的操作。

支持的元素类型

元素复制剪切
<input>支持支持
<textarea>支持支持
<select>支持--
contenteditable 元素支持支持
普通元素(div, span 等)支持--

浏览器兼容性

NowClipboard 优先使用现代 Clipboard API,并自动降级到 execCommand 以支持旧版浏览器。


Chrome

Edge

Firefox

Safari

Opera

IE
66+ ✅79+ ✅63+ ✅13.1+ ✅53+ ✅9+ ✅
Clipboard API(现代方案)execCommand(降级)

💡 如果需要支持旧版浏览器,NowClipboard 会自动降级到 execCommand 方案。你只需在 error 事件中提示用户手动 Ctrl+C 即可。

与 ClipboardJS 的区别

对比项ClipboardJSNowClipboard.js
复制方式execCommandClipboard API + execCommand 降级
图片复制不支持支持(Blob/File/Img/Canvas/URL/data: URL)
富文本复制不支持支持(HTML + 纯文本同时复制)
读取剪贴板不支持支持(浏览器 + Node.js)
富内容读取不支持支持(readRich:文本+HTML+图片)
粘贴监听不支持支持(onPaste + 自动解析)
变更监听不支持支持(onChange 轮询检测)
多格式写入不支持支持(writeFormats 一次写入多种 MIME)
Node.js 写入图片不支持支持(writeImage Buffer/文件路径)
剪贴板历史不支持支持(History 类 + 搜索 + 持久化)
跨标签页同步不支持支持(onSync BroadcastChannel)
权限检测不支持支持(queryPermission)
异步同步Promise-based
重试可配置重试 + 指数退避 + 超时 + AbortSignal
Node.js不支持支持 (Win/Mac/Linux)
TypeScript无类型定义内置 .d.ts 类型定义
ESM不支持支持(ESM + UMD 双格式)
iOS Safari未适配自动降级适配
代码压缩混淆可读、带注释
销毁基础完善(防内存泄漏 + destroy 后保护)

完整示例

交互式演示

项目包含一个交互式演示页面 demo.html,可在线体验所有功能:

# 启动本地服务器(推荐,剪贴板 API 需要 HTTP/HTTPS 环境)
npx serve .
# 然后访问 http://localhost:3000/demo.html

⚠️ 不推荐直接用 file:// 协议打开,浏览器不会为本地文件持久化剪贴板读取权限,会导致反复弹出授权弹窗。

代码示例

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>NowClipboard Demo</title>
</head>
<body>
  <input id="source" value="这是要复制的内容" style="width: 300px;">
  <button class="copy-btn" data-nc-target="#source">复制输入框</button>
  <button class="copy-btn" data-nc-text="直接复制这段文字">复制文本</button>
  <p id="result"></p>

  <script src="NowClipboard.js"></script>
  <script>
    var clipboard = new NowClipboard('.copy-btn');
    var result = document.getElementById('result');

    clipboard.on('success', function (e) {
      result.textContent = '复制成功: ' + e.text;
      e.clearSelection();
    });

    clipboard.on('error', function (e) {
      result.textContent = '复制失败: ' + e.error.message;
    });
  </script>
</body>
</html>

许可证

MIT

Keywords

clipboard

FAQs

Package last updated on 28 May 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts