应使用 DOMParser 解析 HTML 后遍历删除 data-* 属性、style 和 class,再插入 cleaned DOM;需拦截 paste 事件、防止默认行为,并全树扫描而非仅 body。

怎么识别 Word 复制来的污染属性
从 Word、Outlook 或 Office 365 网页版复制内容到编辑器后,DOM 中常出现 data-ccp-props、data-ccp-parastyle、data-contrast 这类非标准属性,还有大量带 SCXW、BCX8 等无意义类名的元素。它们不是你写的,是 Office 剪贴板协议自动注入的私有元数据,只在 Office 生态内有意义,对 Web 渲染、可访问性、SEO 和现代框架(React/Vue)毫无价值,反而会:触发 HTML5 验证警告;干扰编辑器的 DOM 解析逻辑;增大传输体积;导致样式冲突或 XSS 风险。
用 DOMParser + querySelectorAll 安全删除 data-* 属性
别用正则匹配 data-ccp-.*="[^"]*" —— 它无法处理换行、转义引号、嵌套结构,还可能误删注释或 script 内容。正确做法是先解析再遍历:
- 用
new DOMParser().parseFromString(html, 'text/html')得到独立文档对象 - 调用
doc.querySelectorAll('[data-ccp-props], [data-ccp-parastyle], [data-contrast]')精准定位目标节点 - 对每个匹配节点执行
el.removeAttribute('data-ccp-props')等操作(注意:不是setAttribute('data-ccp-props', ''),空值仍会被匹配) - 若需批量清理所有
data-*,可用el.attributes遍历并过滤以data-开头的名
顺手清除 style 和 class 才算真正干净
data-ccp-props 往往和冗余 style、class 共存。仅删 data 属性不够:
- 执行
doc.querySelectorAll('*[style]')后逐个removeAttribute('style'),比正则安全得多 - 对含 Office 类名的元素(如
class="SCXW BCX8"),直接el.removeAttribute('class'),不要留空 class - 避免用
innerHTML.replace()处理整个字符串 —— 它对<img alt=">">、注释、CDATA 段完全失效 - 如果最终要纯文本,取
doc.body?.textContent || doc.documentElement.textContent,再.replace(/\s+/g, ' ').trim()压缩空白
监听 paste 时必须 preventDefault 并手动插入
在 contenteditable 区域里,不拦截默认行为,浏览器就会把原始污染 HTML 直接塞进去,清洗就晚了:
立即学习“前端免费学习笔记(深入)”;
- 必须在
paste事件中调用event.preventDefault() - 用
event.clipboardData.getData('text/html')获取原始 HTML(Safari 不支持时 fallback 到text/plain并清理\u200b) - 清洗后,用
getSelection().getRangeAt(0).insertNode(cleanFragment)插入,确保光标位置准确 -
contenteditable="plaintext-only"不可靠 —— 目前只有 Safari 支持,且无法控制段落结构
实际清理中最容易被忽略的是:data-ccp-props 往往藏在 <span></span> 或 <p></p> 的深层子节点里,而 DOMParser 解析后,这些节点可能不在 body 下,而在 head 或注释旁——务必查 doc.documentElement 全树,不能只扫 body。



















