uni-app富文本长按复制需绕过selectable属性,统一用@longpress事件配合uni.setClipboardData实现;H5需user-select: text,小程序需真机调试且配置selectable="true",App端必须禁用selectable并注入CSS与权限。

uni-app 本身不支持直接复制富文本(HTML 格式)到系统剪贴板,navigator.clipboard.writeText 和 uni.setClipboardData 都只接受纯文本字符串。所谓“复制富文本”,实际是指让用户能长按选中并复制渲染后的可见文字——不是复制 HTML 源码,而是复制渲染结果。
rich-text 组件的 selectable 属性为什么不起作用
很多开发者写了 <rich-text :nodes="nodes" selectable></rich-text> 却发现 iOS 或小程序里完全无法长按选中。根本原因在于:selectable 是个布尔属性,但 uni-app 的 rich-text 在非 H5 端并不自动透传该行为到底层原生组件;而且即使设了,iOS WebView 还需要显式 CSS 支持。
-
selectable必须写成:selectable="true"(不能只写selectable),否则在某些编译模式下会被忽略 - 必须额外加内联样式
style="user-select: text; -webkit-user-select: text;",否则 iOS 和部分安卓 WebView 会禁用选择 - 微信小程序中,
rich-text的selectable仅对纯文本节点生效,含<img>、<br>或嵌套标签的片段可能被截断或跳过
text + v-html 方案的坑:空格丢失、换行错乱、中文乱码
有人改用 <text v-html="htmlStr" selectable></text>,看似简单,实则高危。v-html 渲染后生成的是普通 DOM 节点(H5)或模拟节点(小程序/APP),但 text 组件不解析 HTML,它只是把整个字符串当作文本内容显示,导致:
- 原始 HTML 中的
、<br>、<p>全部变成不可见字符或乱码 - 用户长按选中时,实际拿到的是带标签符号的原始字符串(比如 “<span>你好</span>”),粘贴出来就是源码而非“你好”
- 安卓端常出现首尾空格被自动 trim,中间多个空格坍缩为一个
正确做法是先用 DOMParser 或正则提取纯文本(例如 htmlStr.replace(/]*>/g, '').replace(/\s+/g, ' ').trim()),再喂给 <text selectable> ——但这等于放弃了格式保留,仅解决“能复制”的问题。
mp-html 插件为何更可靠
如果你真需要兼顾格式与可复制性,mp-html 是目前最稳定的方案。它不是简单渲染 HTML,而是将节点转为平台原生可交互组件,并主动注入 user-select 和事件代理逻辑。
- 默认开启长按复制(无需手动加
selectable),且对<strong>、<em>、<p>等标签做语义化包裹,保障选区连续 - 内部已处理 iOS 的
-webkit-user-select和小程序的catchtouchstart冲突问题 - 若需自定义复制行为(比如过滤广告文案),可用
@copy事件拦截,拿到的是 clean text,不是 HTML
示例:
<mp-html :content="htmlStr" @copy="onCopy" />,其中
onCopy 回调的参数是已清洗过的纯文本,可直接用于 uni.setClipboardData 或二次加工。
APP 端长按无反应?重点检查权限和 WebView 配置
Android 或 iOS App 打包后长按失灵,90% 不是代码问题,而是环境限制:
- iOS:确认
Info.plist中未禁用UIUserInterfaceStyle或启用了WKWebView的allowsInlineMediaPlayback等干扰项;真机调试时打开 Web Inspector 查看目标节点是否真有user-select: text - Android:某些厂商(如华为、小米)系统会默认关闭「后台运行」权限,导致 WebView 剪贴板 API 被静默拒绝;需引导用户手动开启「允许后台活动」
- 所有 APP 端:不要在
onLoad或mounted里自动触发复制,必须由用户点击或长按手势触发,否则 iOS 会直接报DOMException: Document is not focused
真正难的不是让文字“看起来能复制”,而是让同一段 HTML,在 H5、微信小程序、支付宝小程序、iOS App、Android App 上,都稳定响应长按、正确划定选区、不丢字不乱码——这需要逐端验证,而不是写一次就完事。


















