【问题标题】:Document.execCommand() works only in developer toolsDocument.execCommand() 仅适用于开发人员工具
【发布时间】:2018-07-25 22:51:35
【问题描述】:

我正在尝试将网页的所有链接复制到剪贴板。我正在尝试将所有锚标记加入一个字符串,将该字符串放入一个输入字段,然后通过document.execCommand("copy") 复制它,但不知何故document.execCommand("copy") 仅适用于浏览器开发人员工具。我希望它在网页中加载的脚本中工作。请帮助我,在此先感谢。

var
body = document.querySelector("body"),
input = document.createElement("textarea"),
a = document.getElementsByTagName("a"),
list = [],
anchor = document.createElement("a");
for (let i = 0; i < a.length; i++){
    list.push(a[i]);
};
list = list.join("\r\n");
input.value = list;
input.setAttribute("readonly", "");
input.style = "position: absolute; left: -9999px;";
body.appendChild(input);
input.select();
document.execCommand('copy');
body.removeChild(input);
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>test</title>
    </head>
<body>
    <a href="http://ali.com">sample link</a>
    <script src="script.js"></script>
</body>
</html>

【问题讨论】:

    标签: javascript html anchor developer-tools execcommand


    【解决方案1】:

    需要注意的是execCommand('copy') 只能在用户调用 操作的上下文中可靠地工作。换句话说,如果你想将数据复制到剪贴板,这应该作为用户点击按钮的副作用来完成。

    例如,您可以按如下方式修改您的脚本 - 在 click 事件处理程序中调用 execCommand(),以实现所需的复制到剪贴板行为:

    var
    body = document.querySelector("body"),
    input = document.createElement("textarea"),
    a = document.getElementsByTagName("a"),
    anchor = document.createElement("a");
    
    input.setAttribute("readonly", "");
    
    // Added a copy button for the purpose of this demonstration
    var copyButton = document.createElement("button")
    copyButton.innerText = 'Copy'
    
    // The event in which the copy to clip board will occour
    copyButton.addEventListener('click', () => {
    
        // This code is in the context of a user 'click' action 
        var list = []
        for (let i = 0; i < a.length; i++){
            list.push(a[i]);
        };
        list = list.join("\r\n");
    
        body.appendChild(input);
        input.value = list;
        input.focus();
        input.select();
    
        // exec copy command is now being called in the context of 
        // a user invoked interaction (ie click), so it should work
        // as expected
        if(document.execCommand('copy')) {
            console.log('copy success')
        }
        else {
            console.log('copy failed')
        }
        body.removeChild(input);
    })
    
    body.appendChild(copyButton);
    

    【讨论】:

    • 如果我想自动点击按钮怎么办?
    • 我不相信这会起作用 - 根据过去的经验,我发现来自 js 的可靠剪贴板交互需要真正来自用户的调用(即不模拟用户交互)
    • 基本上我正在尝试创建一个 chrome 扩展,所以我应该添加两个按钮,说复制到剪贴板并下载?你认为这个脚本在 chrome 扩展中会起作用吗?
    • 是的,我建议您添加一个按钮供用户单击,以便将链接数据复制到剪贴板。这将是实现这一目标的最可靠方法 - 它应该在您的 chrome 扩展程序的上下文中工作
    • @AliRaza 如果您正在编写 chrome 扩展程序,您为什么不在问题中这么说?这是一个重要的信息,因为您可以访问比不受信任的 Web API 更强大的 API。例如,要写入剪贴板,您有一个名为clipboardRead 的权限字段。使用此权限集,您将不会面临用户手势限制。扩展的另一种方法是将数据发送到后台脚本,然后从那里以shown here 执行复制到剪贴板。
    【解决方案2】:

    当用户点击窗口时,您可以使用 Javascript 执行复制功能。复制到剪贴板需要由用户的操作(即点击)触发。

    <a href="http://ali.com">sample link</a>
    <script>
    var copied = false
    window.onclick = function(e){
      if(!copied){
       copy();
       copied = true;
       e.target.focus();//focus back on target of click to prevent constant blurring of first click
       }
    }
    function copy(){
    	 var
    body = document.body,
    input = document.createElement("textarea"),
    a = document.getElementsByTagName("a"),
    list = [],
    anchor = document.createElement("a");
    for (let i = 0; i < a.length; i++){
       list.push(a[i]);
    };
    list = list.join("\r\n");
    input.value = list;
    input.setAttribute("readonly", "true");
    input.style = "position: absolute; left: -9999px;";
    document.body.appendChild(input);
    input.select();
    document.execCommand('copy');
    input.remove();
    }
    </script>
    <button id="hidden" onClick="copy()" style="display: none;">
    </button>
    <br/>
    <textarea placeholder="Paste the copied text"></textarea>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-01-19
      • 1970-01-01
      • 2015-11-30
      • 2010-11-01
      • 2013-07-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多