发布时间:2025-12-10 11:20:56 浏览次数:2
navigator.clipboard.writeText方法返回一个Promise对象实例。
如果使用iframe跨域的情况需要启用Permissions Policy,在创建iframe的dom对象时给allow属性赋值“clipboard-write”启用剪贴板写的权限, 需要读的权限则再加上“clipboard-read”。若已经挂载到domtree中并在html中被渲染后,再使用控制台更改allow属性是不行的,会被浏览器视为无权限。
模拟用户操作,调用document.execCommand("copy")的API,这里提供两种思路,一种是强制给ClipboardEvent对象强制写入值,但注意要阻止默认事件,否则会被复写。代码如下:
const copyFunc = (str) => {const inject = e => {e.preventDefault();e.clipboardData && e.clipboardData.setData("text/plain", str);document.removeEventListener("copy", inject, false);}document.addEventListener("copy", inject, false);document.execCommand("copy");}另一种思路是创建一个文本选区,然后再执行document.execCommand("copy")复制文本,这个实现和用户实际操作非常接近了,以下提供两种方法。
这里可以用document.createRange方法来创建一个选区,代码如下:
假如我们创建的dom是input元素,还可以取一个巧,调用dom的API——select方法,可以直接创建一个本文选区,可以少写一些代码。代码如下:
const copyFunc = (str) => {const oDom = document.createElement("input");oDom.value = str;document.body.appendChild(oDom);oDom.select();document.execCommand("copy");document.body.removeChild(oDom);}document.execCommand这个API目前浏览器还支持,但由于安全问题在新规范中这个API已经被移除了,兴许某天浏览器不再兼容也说不定。官方给出的代替方案就是本文的1号方法。
Chrome内核浏览器有个API——document.dispatchEvent,这个API可以模拟触发一个事件,现在我们将用它来代替document.execCommand方法。另w3c规范中提供了构造函数ClipboardEvent来创建一个剪贴板事件对象,这个规范已经在各大浏览器中实践了可以正常使用。如果模拟一个自定义的copy事件应该能实现吧:
const copyFunc = (str) => {const clipboardEvent = new ClipboardEvent("copy", {clipboardData: new DataTransfer("text/plain", str)});document.dispatchEvent(clipboardEvent);}实测不能,那如果仅模拟触发一个copy事件,再回调中用setData方法注入数据,也许能行?
const copyFunc = (str) => {const clipboardEvent = new ClipboardEvent("copy");const inject = e => {e.clipboardData && e.clipboardData.setData("text/plain", str);document.removeEventListener("copy", inject, false);}document.addEventListener("copy", inject, false);document.dispatchEvent(clipboardEvent);}事件实测是可以触发的,也可以打印出这个e参数;但实际这个e.clipboardData的值为null,所以压根不会执行后面的方法。再优化一下:
const copyFunc = (str) => {const clipboardEvent = new ClipboardEvent("copy", {clipboardData: new DataTransfer("text/plain", "")});const inject = e => {// e.preventDefault() 这里已经当作默认事件处理了,加不加不影响e.clipboardData && e.clipboardData.setData("text/plain", str);document.removeEventListener("copy", inject, false);}document.addEventListener("copy", inject, false);document.dispatchEvent(clipboardEvent);}很遗憾,实测依然不行。具体原因未知,但思路应该没有问题,如果有知道怎么解决的还请告知。
以上。实现很简单,但管理各种库才是麻烦事!尽量少用。