document.execCommand('copy') 异步复制失败

3,369 阅读3分钟

Document.execCommand()

MDN Web Docs: Document.execCommand()

Deprecated

This feature is no longer recommended. Though some browsers might still support it, it may have already been removed from the relevant web standards, may be in the process of being dropped, or may only be kept for compatibility purposes. Avoid using it, and update existing code if possible; see the compatibility table at the bottom of this page to guide your decision. Be aware that this feature may cease to work at any time.

已弃用

不再推荐此功能。虽然一些浏览器可能仍然支持它,但它可能已经从相关的 Web 标准中删除,可能正在被删除,或者可能只是为了兼容性目的而保留。避免使用它,并尽可能更新现有代码;请参阅本页底部的兼容性表以指导您的决定。请注意,此功能可能随时停止工作。

已弃用。不适用于新网站。谷歌浏览器目前支持常用copy and cut command

Syntax

document.execCommand(aCommandName, aShowDefaultUI, aValueArgument)

Return Value

返回一个布尔值,如果命令不被支持或禁用,则为false。

注意:document.execCommand() 仅在作为用户交互的一部分被调用时才返回 true。在调用命令之前,您不能使用它来验证浏览器支持。从 Firefox 82 开始,嵌套的 document.execCommand() 调用将始终返回 false。

Parameters

aCommandName

DOMString,执行的命令名称,目前常用的有cut, copy

aShowDefaultUI

布尔值,指示是否应该显示默认的用户界面。这在Mozilla中没有实现。

aValueArgument

对于需要输入参数的命令,是提供该信息的DOMString。例如,insertImage 需要插入图像的 URL。如果不需要参数,则指定 null。

Copy command

将当前选择复制到剪贴板。启用此行为的条件因浏览器而异,并且随着时间的推移而演变。检查兼容性表以确定您是否可以在您的情况下使用它。

Feedback

正常情况下document.execCommand('copy')执行复制剪切板功能没有问题,但是如何在js异步中执行会有问题,导致复制失败

代码模拟

<input type="text" id="copyVal" value="被复制的内容">
<button onclick="copyText()">复制</button>
function onCopy () {
    const key = document.execCommand('copy')
    if (key) {
        console.log('复制成功')
    } else {
        console.log('复制失败')
    }
}
function copyText () {
    const dom = document.getElementById('copyVal')
    const randomVal = Math.random()
    dom.value = randomVal
    dom.select()
    // selectVal() // 复制成功
    asyncSelectVal(3000) // 复制成功
    asyncSelectVal(4000) // 复制失败
}
function selectVal () {
    onCopy()
}
function asyncSelectVal (delay = 3000) {
    setTimeout(() => {
        onCopy()
    }, delay)
}

使用'setTimeout'模拟异步发现,3s内执行复制成功,3s后复制失败,当然这是有随机性,在谷歌浏览器测试的,不同的浏览器厂商支持不同

You can only trigger a copy to the system clipboard in direct response to a trusted user action, such as a click event.

为了安全考虑,document.execCommand('copy')的执行操作必须是真正的用户触发的(仅在作为用户交互的一部分被调用时才返回 true),chrome下应该是有用户操作变量userAction,但是这个变量有时效性,也就说你的异步请求如果快的话,大概率是可以复制成功;但是异步请求是不确定的,如果超出userAction的时效时间(目前测试界定在3s左右),Chrome就会判定非用户操作行为阻止命令执行,最终复制失败;

所以涉及异步操作的复制剪切板功能,最好放在异步请求之后再由用户手动触发复制功能最为稳妥; 当然不同浏览器支持有所不同,目前就Chrome而言,一点拙见,可能理解不太准确深入欢迎指教