应优先使用 event.clipboardData.getData('text/plain') 提取纯文本,兼容性好;HTTPS 环境下可降级使用 navigator.clipboard.readText();再通过正则清理零宽字符等残留格式,避免破坏段落结构。

在 paste 事件中提取纯文本并去除格式,**不依赖事件捕获或冒泡机制本身**,而是利用事件对象的剪贴板 API(如 event.clipboardData 或现代的 event.preventDefault() + navigator.clipboard.readText()),再配合文本清理逻辑。事件捕获/冒泡只影响监听时机和传播路径,对内容提取无直接作用。
用 event.clipboardData.getData('text/plain') 提取纯文本
这是最兼容、最常用的方式,适用于绝大多数 paste 场景(包括富文本粘贴):
- 在
paste事件监听器中调用event.preventDefault()阻止默认粘贴行为 - 从
event.clipboardData中读取'text/plain'类型内容,它会自动降级为纯文本(即使复制的是 HTML 或 Word 内容) - 若
clipboardData为空(如某些沙盒环境),可回退到document.execCommand('insertText', false, text)或手动插入
示例:
input.addEventListener('paste', function (e) {
e.preventDefault();
const plainText = e.clipboardData?.getData('text/plain') || '';
// 此时 plainText 已是无格式纯文本(换行符保留,但无 HTML 标签、样式等)
console.log(plainText);
// 手动插入到输入框
document.execCommand('insertText', false, plainText);
});
用 navigator.clipboard.readText() 获取更干净的文本(需 HTTPS + 用户交互)
该 API 更现代,支持异步读取,且返回内容完全由系统剪贴板提供,不受页面上下文限制:
立即学习“Java免费学习笔记(深入)”;
- 必须在安全上下文(HTTPS 或 localhost)中运行
- 必须在用户手势(如 click、paste)触发的回调内调用,否则被浏览器拒绝
- 返回 Promise,需 await 或 .then() 处理;失败时需降级到
clipboardData方案
示例:
input.addEventListener('paste', async function (e) {
e.preventDefault();
let text = '';
try {
text = await navigator.clipboard.readText();
} catch (err) {
// 降级:使用 clipboardData
text = e.clipboardData?.getData('text/plain') || '';
}
// 可选:进一步清理(如去掉首尾空格、合并连续空白)
text = text.trim().replace(/\s+/g, ' ');
input.value += text;
});
手动清理残留格式痕迹(如 Word 粘贴产生的不可见字符)
即使拿到 text/plain,某些来源(如 Microsoft Word)仍可能混入零宽空格(\u200B)、软连字符(\u00AD)、特殊空格(\u00A0)等:
- 用正则统一替换常见不可见控制字符:
text.replace(/[\u200B-\u200F\u202A-\u202E\uFEFF\u00A0\u00AD]/g, '') - 若需严格纯 ASCII,可额外过滤非基本拉丁字母、数字、常见标点外的字符
- 注意:不要盲目用
.replace(/\s+/g, ' ')替换所有空白——这会破坏段落结构;建议仅处理首尾或按需标准化换行
捕获 vs 冒泡在 paste 中的实际意义很小
paste 事件默认在**冒泡阶段**触发,且大多数场景下无需主动切换到捕获阶段:
- 除非你在父容器(如
div#editor)上监听 paste,并希望在子元素(如contenteditable)触发前拦截处理,才需要{ capture: true } - 但即便如此,提取剪贴板文本的方式不变,只是监听位置和时机不同
- 绝大多数情况直接在目标元素上监听(冒泡默认行为)即可,简洁可靠


















