How do I copy to the clipboard in JavaScript?

2020-01-22 11:10发布

What is the best way to copy text to the clipboard? (multi-browser)

I have tried:

function copyToClipboard(text) {
    if (window.clipboardData) { // Internet Explorer
        window.clipboardData.setData("Text", text);
    } else {  
        unsafeWindow.netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");  
        const clipboardHelper = Components.classes["@mozilla.org/widget/clipboardhelper;1"].getService(Components.interfaces.nsIClipboardHelper);  
        clipboardHelper.copyString(text);
    }
}

but in Internet Explorer it gives a syntax error. In Firefox, it says unsafeWindow is not defined.

A nice trick without flash: How does Trello access the user's clipboard?

30条回答
The star\"
2楼-- · 2020-01-22 11:13

Automatic copying to clipboard may be dangerous, therefore most browsers (except IE) make it very difficult. Personally, I use the following simple trick:

function copyToClipboard(text) {
  window.prompt("Copy to clipboard: Ctrl+C, Enter", text);
}

The user is presented with the prompt box, where the text to be copied is already selected. Now it's enough to press Ctrl+C and Enter (to close the box) -- and voila!

Now the clipboard copy operation is SAFE, because the user does it manually (but in a pretty straightforward way). Of course, works in all browsers.

<button id="demo" onclick="copyToClipboard(document.getElementById('demo').innerHTML)">This is what I want to copy</button>

<script>
  function copyToClipboard(text) {
    window.prompt("Copy to clipboard: Ctrl+C, Enter", text);
  }
</script>

查看更多
放我归山
3楼-- · 2020-01-22 11:13

As of Flash 10, you can only copy to clipboard if the action originates from user interaction with a Flash object. (Read related section from Adobe's Flash 10 announcement)

The solution is to overly a flash object above the Copy button, or whatever element initiates the copy. Zero Clipboard is currently the best library with this implementation. Experienced Flash developers may just want to make their own library.

查看更多
淡お忘
4楼-- · 2020-01-22 11:14

Here is my take on that one...

function copy(text) {
    var input = document.createElement('input');
    input.setAttribute('value', text);
    document.body.appendChild(input);
    input.select();
    var result = document.execCommand('copy');
    document.body.removeChild(input);
    return result;
 }
查看更多
成全新的幸福
5楼-- · 2020-01-22 11:15

This was the only thing I ever got working, after looking up various ways all around the Internet. This is a messy topic. There are lots of solutions posted around the world and most of them do not work. This worked for me:

NOTE: This code will only work when executed as direct synchronous code to something like an 'onClick' method. If you call in an asynchronous response to Ajax or in any other asynchronous way it will not work.

copyToClipboard(text) {
    var copyText = document.createElement("input");
    copyText.type = "text";
    document.body.appendChild(copyText);
    copyText.style = "display: inline; width: 1px;";
    copyText.value = text;
    copyText.focus();
    document.execCommand("SelectAll");
    document.execCommand("Copy");
    copyText.remove();
}

I do realize this code will show a 1-pixel wide component visibly on the screen for a millisecond, but decided not to worry about that, which is something that others can address if a real problem.

查看更多
Explosion°爆炸
6楼-- · 2020-01-22 11:16

The following approach works in Chrome, Firefox, Internet Explorer and Edge, and in recent versions of Safari (copy support was added in version 10 which was released Oct 2016).

  • Create a textarea and set its contents to the text you want copied to the clipboard.
  • Append the textarea to the DOM.
  • Select the text in the textarea.
  • Call document.execCommand("copy")
  • Remove the textarea from the dom.

Note: you will not see the textarea, as it is added and removed within the same synchronous invocation of Javascript code.

Some things to watch out for if you are implementing this yourself:

  • For security reasons, this can only called from an event handler such as click (Just as with opening windows).
  • Internet Explorer will show a permission dialog the first time the clipboard is updated.
  • Internet Explorer, and Edge will scroll when the textarea is focused.
  • execCommand() may throw in some cases.
  • Newlines and tabs can get swallowed unless you use a textarea. (Most articles seem to recommend using a div)
  • The textarea will be visible while the Internet Explorer dialog is shown, you either need to hide it, or use the Internet Explorer specific clipboardData API.
  • In Internet Explorer system administrators can disable the clipboard API.

The function below should handle all of the following issues as cleanly as possible. Please leave a comment if you find any problems or have any suggestions for improving it.

// Copies a string to the clipboard. Must be called from within an
// event handler such as click. May return false if it failed, but
// this is not always possible. Browser support for Chrome 43+,
// Firefox 42+, Safari 10+, Edge and Internet Explorer 10+.
// Internet Explorer: The clipboard feature may be disabled by
// an administrator. By default a prompt is shown the first
// time the clipboard is used (per session).
function copyToClipboard(text) {
    if (window.clipboardData && window.clipboardData.setData) {
        // Internet Explorer-specific code path to prevent textarea being shown while dialog is visible.
        return clipboardData.setData("Text", text);

    }
    else if (document.queryCommandSupported && document.queryCommandSupported("copy")) {
        var textarea = document.createElement("textarea");
        textarea.textContent = text;
        textarea.style.position = "fixed";  // Prevent scrolling to bottom of page in Microsoft Edge.
        document.body.appendChild(textarea);
        textarea.select();
        try {
            return document.execCommand("copy");  // Security exception may be thrown by some browsers.
        }
        catch (ex) {
            console.warn("Copy to clipboard failed.", ex);
            return false;
        }
        finally {
            document.body.removeChild(textarea);
        }
    }
}

https://jsfiddle.net/fx6a6n6x/

查看更多
Anthone
7楼-- · 2020-01-22 11:16

This is a bit of a combination between the other answers.

var copyToClipboard = function(textToCopy){
    $("body")
        .append($('<textarea name="fname" class="textToCopyInput"/>' )
        .val(textToCopy))
        .find(".textToCopyInput")
        .select();
      try {
        var successful = document.execCommand('copy');
        var msg = successful ? 'successful' : 'unsuccessful';
        alert('Text copied to clipboard!');
      } catch (err) {
          window.prompt("To copy the text to clipboard: Ctrl+C, Enter", textToCopy);
      }
     $(".textToCopyInput").remove();
}

It uses jQuery, but it doesn't have to of course. You can change that if you want. I just had jQuery to my disposal. You can also add some CSS to make sure the input doesn't show. For instance something like:

.textToCopyInput{opacity: 0; position: absolute;}

Or of course you could also do some inline styling

.append($('<textarea name="fname" style="opacity: 0;  position: absolute;" class="textToCopyInput"/>' )
查看更多
登录 后发表回答