在 Chrome 扩展程序中复制到剪贴板

问题描述 投票:0回答:12

我正在为 Google Chrome 制作扩展程序,但遇到了障碍。

我需要在弹出窗口中单击时将只读文本区域的内容复制到剪贴板。有谁知道用纯Javascript而不用Flash来解决这个问题的最佳方法吗?我还在扩展中加载了 jQuery,如果有帮助的话。我当前的(非工作)代码是...

function copyHTMLCB() {
$('#lb_html').select();
$('#lb_html').focus();
textRange = document.lb_html_frm.lb_html.createTextRange();
textRange.execCommand("RemoveFormat");
textRange.execCommand("Copy");
alert("HTML has been copied to your clipboard."); }
javascript clipboard google-chrome-extension
12个回答
68
投票

所有功劳都归功于 joelpt,但如果其他人需要这个在没有 jQuery 的纯 javascript 中工作(我就是这么做的),这里是他的解决方案的改编版:

function copyTextToClipboard(text) {
  //Create a textbox field where we can insert text to. 
  var copyFrom = document.createElement("textarea");

  //Set the text content to be the text you wished to copy.
  copyFrom.textContent = text;

  //Append the textbox field into the body as a child. 
  //"execCommand()" only works when there exists selected text, and the text is inside 
  //document.body (meaning the text is part of a valid rendered HTML element).
  document.body.appendChild(copyFrom);

  //Select all the text!
  copyFrom.select();

  //Execute command
  document.execCommand('copy');

  //(Optional) De-select the text using blur(). 
  copyFrom.blur();

  //Remove the textbox field from the document.body, so no other JavaScript nor 
  //other elements can get access to this.
  document.body.removeChild(copyFrom);
}

44
投票

我发现以下方法效果最好,因为它可以让您指定复制数据的 MIME 类型:

copy: function(str, mimeType) {
  document.oncopy = function(event) {
    event.clipboardData.setData(mimeType, str);
    event.preventDefault();
  };
  document.execCommand("copy", false, null);
}

22
投票

我正在使用这个简单的函数将任何给定的纯文本复制到剪贴板(仅限 Chrome,使用 jQuery):

// Copy provided text to the clipboard.
function copyTextToClipboard(text) {
    var copyFrom = $('<textarea/>');
    copyFrom.text(text);
    $('body').append(copyFrom);
    copyFrom.select();
    document.execCommand('copy');
    copyFrom.remove();
}

// Usage example
copyTextToClipboard('This text will be copied to the clipboard.');

由于快速的追加-选择-复制-删除序列,似乎没有必要隐藏文本区域或为其提供任何特定的 CSS/属性。至少在我的机器上,Chrome 在删除之前甚至不会将其渲染到屏幕上,即使有非常大的文本块。

请注意,这适用于 Chrome 扩展程序/应用程序。如果您使用的是 v2 manifest.json,您应该在那里声明“clipboardWrite”权限;这对于应用程序是强制性的,并且建议对于扩展程序。


19
投票

Chrome 现已支持 Clipboard API,旨在取代

document.execCommand

来自MDN:

navigator.clipboard.writeText(text).then(() => {
    //clipboard successfully set
}, () => {
    //clipboard write failed, use fallback
});

6
投票

您可以使用 Experimental Clipboard API 复制到剪贴板,但它仅在浏览器的开发分支中可用,并且默认情况下不启用(更多信息)..


3
投票

您无法使用

execCommand("Copy")
复制只读文本位,它必须是可编辑的文本区域。解决方案是创建一个文本输入元素并从那里复制文本。不幸的是,您无法使用
display: none
visibility: hidden
隐藏该元素,因为这也会阻止选择/复制命令工作。但是,您可以使用负边距“隐藏”它。这是我在获取短网址的 Chrome 扩展弹出窗口中所做的操作。这是用短网址重写弹出窗口的代码(快速而肮脏的方法;-)):

document.body.innerHTML = '<p><a href="'+shortlink+'" target="_blank" >'+shortlink+'</a><form style="margin-top: -35px; margin-left: -500px;"><input type="text" id="shortlink" value="'+shortlink+'"></form></p>'
document.getElementById("shortlink").select()
document.execCommand("Copy") 

2
投票

只有这个对我有用。

document.execCommand 在我看来根本不适用于 chrome。

我把 execCommand 留在了代码中,但可能是出于一个简单的原因:所以这个狗屎就在那里:)

我在这上面浪费了很多时间,而不是浏览我的旧笔记。

    function copy(str, mimeType) {
        document.oncopy = function(event) {
            event.clipboardData.setData(mimeType, str);
            event.preventDefault();
        };
        try{            
            var successful = document.execCommand('copy', false, null);
            var msg = successful ? 'successful' : 'unsuccessful';
            console.log('Copying text command was ' + msg);
            if (!successful){
                navigator.clipboard.writeText(str).then(
                    function() {
                        console.log('successful')
                    }, 
                    function() {
                        console.log('unsuccessful')
                    }
                );
            }
        }catch(ex){console.log('Wow! Clipboard Exeption.\n'+ex)}
    }

1
投票

我在某处读到,Javascript 存在安全限制,会阻止您与操作系统交互。我过去使用 ZeroClipboard 取得了很好的成功 (http://code.google.com/p/zeroclipboard/),但它确实使用 Flash。 Bitly 网站非常有效地使用它:http://bit.ly/


1
投票
let content = document.getElementById("con");
content.select();
document.execCommand("copy");

上面的代码在任何情况下都可以正常工作。只需确保您从中获取内容的字段应该是可编辑字段,如输入字段。


0
投票

我遇到了类似的问题,我必须仅使用 javascript 从元素复制文本。我将在这里为感兴趣的人添加该问题的解决方案。该解决方案适用于许多 HTML 元素,包括文本区域。

HTML:

    <textarea id="text-to-copy">This is the text I want to copy</textarea>
    <span id="span-text-to-copy">This is the text I want to copy</span>

Javascript:

let textElement = document.getElementById("text-to-copy");

//remove selection of text before copying. We can also call this after copying
window.getSelection().removeAllRanges();

//create a Range object
let range = document.createRange();

//set the Range to contain a text node.
range.selectNode(textElement);

//Select the text node
window.getSelection().addRange(range);

try {
    //copy text
    document.execCommand('copy');
} catch(err) {
    console.log("Not able to copy ");
}

请注意,例如,如果您想复制 span 元素,那么您可以获取其文本节点并将其用作 range.selectNode() 的参数来选择该文本:

let elementSpan = document.getElementById("span-text-to-copy");
let textNode = elementSpan.childNodes[0];

0
投票

我正在尝试创建一个 chrome 扩展,可以在单击按钮时将数据直接复制到剪贴板中,但我找不到任何与此相关的信息;在这里尝试了很多来自不同线程的东西。

我发现了一个扩展,可以在选择文本后自动复制文本,但它对我不起作用

这个插件对我不起作用,但如果我将其代码粘贴到我自己的扩展中,它就可以正常工作

window.addEventListener(
    'mouseup',
    () => {
        const content = document.getSelection()?.toString();
        if (!content) { return; }

        navigator.clipboard.writeText(content);
    },
    false
);

0
投票

我发现 gjuggler 答案有效,但它会阻止用户在浏览器上进行的任何复制,因此如果您只想在单击按钮时设置一次复制值,请使用这样的功能

function setCopyValueOnce(val){
  function setCopyOnce(event) {
      console.log("hi");
      event.clipboardData.setData('Text', val);
      event.preventDefault();
  }
  document.addEventListener('copy', setCopyOnce);
  document.execCommand("copy", false, null);
  document.removeEventListener('copy', setCopyOnce);
}
setCopyValueOnce($("textarea").val());

我使用removeEventListener来停止创建的复制事件监听器

© www.soinside.com 2019 - 2024. All rights reserved.