How do I copy to the clipboard in JavaScript?

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?


Overview

There are 3 primary browser APIs for copying to the clipboard:

  • Async Clipboard API [navigator.clipboard.writeText]
  • Text-focused portion available in Chrome 66 (March 2018)
  • Access is asynchronous and uses JavaScript Promises, can be written so security user prompts (if displayed) don't interrupt the JavaScript in page.
  • Text can be copied to the clipboard directly from a variable.
  • Only supported on pages served over HTTPS.
  • In Chrome 66 pages in active tabs can write to the clipboard without a permissions prompt.
  • document.execCommand('copy')
  • Most browsers support this as of ~April 2015 (see Browser Support below).
  • Access is synchronous, ie stops JavaScript in the page until complete including displaying and user interacting with any security prompts.
  • Text is read from the DOM and placed on the clipboard.
  • During testing ~April 2015 only Internet Explorer was noted as displaying permissions prompts whilst writing to the clipboard.
  • Overriding the copy event
  • See Clipboard API documentation on Overriding the copy event.
  • Allows you to modify what appear on the clipboard from any copy event, can include other formats of data other than plain text.
  • Not covered here as it doesn't directly answer the question.
  • General development notes

    Don't expect clipboard related commands to work whilst you testing code in the console. Generally the page is required to be active (Async Clipboard API) or requires user interaction (eg a user click) to allow ( document.execCommand('copy') ) to access the clipboard see below for more detail.

    Async + Fallback

    Due to the level of browser support for the new Async Clipboard API you will likely want to fallback to the document.execCommand('copy') method to get good browser coverage.

    Here is a simple example:

    function fallbackCopyTextToClipboard(text) {
      var textArea = document.createElement("textarea");
      textArea.value = text;
      document.body.appendChild(textArea);
      textArea.focus();
      textArea.select();
    
      try {
        var successful = document.execCommand('copy');
        var msg = successful ? 'successful' : 'unsuccessful';
        console.log('Fallback: Copying text command was ' + msg);
      } catch (err) {
        console.error('Fallback: Oops, unable to copy', err);
      }
    
      document.body.removeChild(textArea);
    }
    function copyTextToClipboard(text) {
      if (!navigator.clipboard) {
        fallbackCopyTextToClipboard(text);
        return;
      }
      navigator.clipboard.writeText(text).then(function() {
        console.log('Async: Copying to clipboard was successful!');
      }, function(err) {
        console.error('Async: Could not copy text: ', err);
      });
    }
    
    var copyBobBtn = document.querySelector('.js-copy-bob-btn'),
      copyJaneBtn = document.querySelector('.js-copy-jane-btn');
    
    copyBobBtn.addEventListener('click', function(event) {
      copyTextToClipboard('Bob');
    });
    
    
    copyJaneBtn.addEventListener('click', function(event) {
      copyTextToClipboard('Jane');
    });
    <div style="display:inline-block; vertical-align:top;">
      <button class="js-copy-bob-btn">Set clipboard to BOB</button><br /><br />
      <button class="js-copy-jane-btn">Set clipboard to JANE</button>
    </div>
    <div style="display:inline-block;">
      <textarea class="js-test-textarea" cols="35" rows="4">Try pasting into here to see what you have on your clipboard:
      
      </textarea>
    </div>

    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>

    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).
  • IE will show a permission dialog the first time the clipboard is updated.
  • IE, 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 IE dialog is shown, you either need to hide it, or use the IE specific clipboardData api.
  • In IE 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 IE 10+.
    // IE: 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) {
            // IE 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 MS 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/

    链接地址: http://www.djcxy.com/p/440.html

    上一篇: 改进INSERT

    下一篇: 如何在JavaScript中复制到剪贴板?