给 object 标签容器加 user-select: none 无效,必须用父级 div 包裹并设置全前缀 user-select: none;pdf 场景前端禁复制无效,需服务端控制。

给 object 标签容器加 user-select: none 才有效
object 本身不响应 user-select,它只是嵌入外部资源(如 PDF、SVG、Flash)的容器。真正要禁选中的是其内部渲染出的文本内容——但这些内容通常不在主 DOM 中,无法直接加样式。所以必须作用于包裹它的父元素(比如 <div>),且该父容器需覆盖整个 <code>object 区域。
常见错误是只给 object 自身写 CSS:
object { user-select: none; }
这基本无效,因为浏览器不会把 user-select 继承或透传到内嵌文档里。
- 正确做法:用一个
<div class="no-select"><object></object></div>包裹,并对.no-select设置全前缀user-select - 必须写全:
-webkit-user-select: none、-moz-user-select: none、-ms-user-select: none、user-select: none - 如果
object加载的是 SVG,且 SVG 内有<text></text>元素,可尝试在 SVG 内联加style="user-select:none",但仅对同源且非 iframe 嵌入的 SVG 有效
监听 selectstart 比 oncopy 更早拦截选中动作
用户还没复制,先得能选中。而 object 容器区域的文本选中往往触发的是父容器的 selectstart 事件,不是 copy —— 所以只绑 copy 监听器根本来不及。
实操建议:
- 给包裹
object的父元素绑定selectstart事件并e.preventDefault() - 不要监听
document全局,否则会误杀输入框和按钮的正常聚焦行为 - 示例代码:
document.querySelector('.object-wrapper').addEventListener('selectstart', e => e.preventDefault()); - 注意:移动端长按选中文本时,
selectstart可能不触发,此时依赖 CSS 层更可靠
object 加载 PDF 时,前端禁止复制纯属心理安慰
当 object 嵌入 PDF(如 <object data="doc.pdf"></object>),浏览器用内置 PDF 查看器渲染。这个查看器完全独立于页面 DOM 和 JS 上下文:
-
user-select: none对 PDF 渲染层无任何影响 - JS 事件(
selectstart、copy、contextmenu)全部无法穿透到 PDF 内容区域 - 用户右键 PDF 内容 → “复制文本”,这个菜单由 PDF 查看器原生提供,页面 JS 完全不可控
- 即使禁掉整个页面的右键,PDF 查看器仍可能弹出自带右键菜单(Chrome 最新版已默认启用该行为)
结论:PDF 场景下,所有前端限制都失效。真要防复制,只能服务端控制 PDF 文件本身(如加水印、禁用复制权限位、流式分片加载)。
别忘了 pointer-events: none 会同时禁掉点击和聚焦
有人试图用 pointer-events: none 配合 user-select: none 双重封锁,但这会让 object 完全无法交互:
- PDF 无法翻页、缩放、点击链接
- SVG 内的
<button></button>或<a></a>失效 - 若
object是可访问内容(如无障碍阅读器需要聚焦),此设置直接破坏 a11y - 修复方式:只对文字区域设
pointer-events: none,再显式给交互元素(如工具栏按钮)设回pointer-events: auto
最易被忽略的一点:哪怕你层层设防,用户打开开发者工具 → Elements 面板 → 找到 object 标签 → 点开其 data 属性值 → 直接访问 PDF/SVG 原文件,一切限制瞬间归零。











