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?

Answers:

Answer

Overview

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

  1. 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.
  2. document.execCommand('copy')
    • Most browsers support this as of ~April 2015 (see Browser Support below).
    • Access is synchronous, i.e. 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.
  3. Overriding the copy event
    • See Clipboard API documentation on Overriding the copy event.
    • Allows you to modify what appears 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 are testing code in the console. Generally the page is required to be active (Async Clipboard API) or requires user interaction (e.g. a user click) to allow (document.execCommand('copy')) to access the clipboard see below for more detail.

IMPORTANT (noted here 2020/02/20)

Note that since this post was originally written deprecation of permissions in cross-origin IFRAMEs and other IFRAME "sandboxing" prevents the embedded demos "Run code snippet" buttons and "codepen.io example" from working in some browsers (including Chrome and Microsoft Edge).

To develop create your own web page, serve that page over HTTPS connection to test and develop against.

Here is a test/demo page which demonstrates the code working: https://deanmarktaylor.github.io/clipboard-test/

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 (may not work embedded in this site, read "important" note above):

function fallbackCopyTextToClipboard(text) {
  var textArea = document.createElement("textarea");
  textArea.value = text;
  
  // Avoid scrolling to bottom
  textArea.style.top = "0";
  textArea.style.left = "0";
  textArea.style.position = "fixed";

  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>

(codepen.io example may not work, read "important" note above) Note that this snippet is not working well in Stack Overflow's embedded preview you can try it here: https://codepen.io/DeanMarkTaylor/pen/RMRaJX?editors=1011

Async Clipboard API

Note that there is an ability to "request permission" and test for access to the clipboard via the permissions API in Chrome 66.

var text = "Example text to appear on clipboard";
navigator.clipboard.writeText(text).then(function() {
  console.log('Async: Copying to clipboard was successful!');
}, function(err) {
  console.error('Async: Could not copy text: ', err);
});

document.execCommand('copy')

The rest of this post goes into the nuances and detail of the document.execCommand('copy') API.

Browser Support

The JavaScript document.execCommand('copy') support has grown, see the links below for browser updates:

Simple Example

(may not work embedded in this site, read "important" note above)

var copyTextareaBtn = document.querySelector('.js-textareacopybtn');

copyTextareaBtn.addEventListener('click', function(event) {
  var copyTextarea = document.querySelector('.js-copytextarea');
  copyTextarea.focus();
  copyTextarea.select();

  try {
    var successful = document.execCommand('copy');
    var msg = successful ? 'successful' : 'unsuccessful';
    console.log('Copying text command was ' + msg);
  } catch (err) {
    console.log('Oops, unable to copy');
  }
});
<p>
  <button class="js-textareacopybtn" style="vertical-align:top;">Copy Textarea</button>
  <textarea class="js-copytextarea">Hello I'm some text</textarea>
</p>

Complex Example: Copy to clipboard without displaying input

The above simple example works great if there is a textarea or input element visible on screen.

In some cases you might wish to copy text to the clipboard without displaying an input / textarea element. This is one example of a way to work around this (basically insert element, copy to clipboard, remove element):

Tested with Google Chrome 44, Firefox 42.0a1 and Internet Explorer 11.0.8600.17814.

(may not work embedded in this site, read "important" note above)

function copyTextToClipboard(text) {
  var textArea = document.createElement("textarea");

  //
  // *** This styling is an extra step which is likely not required. ***
  //
  // Why is it here? To ensure:
  // 1. the element is able to have focus and selection.
  // 2. if element was to flash render it has minimal visual impact.
  // 3. less flakyness with selection and copying which **might** occur if
  //    the textarea element is not visible.
  //
  // The likelihood is the element won't even render, not even a
  // flash, so some of these are just precautions. However in
  // Internet Explorer the element is visible whilst the popup
  // box asking the user for permission for the web page to
  // copy to the clipboard.
  //

  // Place in top-left corner of screen regardless of scroll position.
  textArea.style.position = 'fixed';
  textArea.style.top = 0;
  textArea.style.left = 0;

  // Ensure it has a small width and height. Setting to 1px / 1em
  // doesn't work as this gives a negative w/h on some browsers.
  textArea.style.width = '2em';
  textArea.style.height = '2em';

  // We don't need padding, reducing the size if it does flash render.
  textArea.style.padding = 0;

  // Clean up any borders.
  textArea.style.border = 'none';
  textArea.style.outline = 'none';
  textArea.style.boxShadow = 'none';

  // Avoid flash of white box if rendered for any reason.
  textArea.style.background = 'transparent';


  textArea.value = text;

  document.body.appendChild(textArea);
  textArea.focus();
  textArea.select();

  try {
    var successful = document.execCommand('copy');
    var msg = successful ? 'successful' : 'unsuccessful';
    console.log('Copying text command was ' + msg);
  } catch (err) {
    console.log('Oops, unable to copy');
  }

  document.body.removeChild(textArea);
}


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>

Additional notes

Only works if the user takes an action

All document.execCommand('copy') calls must take place as a direct result of a user action, e.g. click event handler. This is a measure to prevent messing with the user's clipboard when they don't expect it.

See the Google Developers post here for more info.

Clipboard API

Note the full Clipboard API draft specification can be found here: https://w3c.github.io/clipboard-apis/

Is it supported?

  • document.queryCommandSupported('copy') should return true if the command "is supported by the browser".
  • and document.queryCommandEnabled('copy') return true if the document.execCommand('copy') will succeed if called now. Checking to ensure the command was called from a user-initiated thread and other requirements are met.

However as an example of browser compatibility issues, Google Chrome from ~April to ~October 2015 only returned true from document.queryCommandSupported('copy') if the command was called from a user-initiated thread.

Note compatibility detail below.

Browser Compatibility Detail

Whilst a simple call to document.execCommand('copy') wrapped in a try/catch block called as a result of a user click will get you the most compatibility use the following has some provisos:

Any call to document.execCommand, document.queryCommandSupported or document.queryCommandEnabled should be wrapped in a try/catch block.

Different browser implementations and browser versions throw differing types of exceptions when called instead of returning false.

Different browser implementations are still in flux and the Clipboard API is still in draft, so remember to do your testing.

Answer

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>

Answer

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/

Answer

If you want a really simple solution (takes less than 5 minutes to integrate) and looks good right out of the box, then Clippy is a nice alternative to some of the more complex solutions.

It was written by a co-founder of GitHub. Example Flash embed code below:

<object
   classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
   width="110"
   height="14"
   id="clippy">
  <param name="movie" value="/flash/clippy.swf"/>
  <param name="allowScriptAccess" value="always"/>
  <param name="quality" value="high"/>
  <param name="scale" value="noscale"/>
  <param NAME="FlashVars" value="text=#{text}"/>
  <param name="bgcolor" value="#{bgcolor}"/>
  <embed
     src="/flash/clippy.swf"
     width="110"
     height="14"
     name="clippy"
     quality="high"
     allowScriptAccess="always"
     type="application/x-shockwave-flash"
     pluginspage="http://www.macromedia.com/go/getflashplayer"
     FlashVars="text=#{text}"
     bgcolor="#{bgcolor}"/>
</object>

Remember to replace #{text} with the text you need copied, and #{bgcolor} with a color.

Answer

Reading and modifying the clipboard from a webpage raises security and privacy concerns. However, in Internet Explorer, it is possible to do it. I found this example snippet:

    <script type="text/javascript">
        function select_all(obj) {
            var text_val=eval(obj);
            text_val.focus();
            text_val.select();
            r = text_val.createTextRange();
            if (!r.execCommand) return; // feature detection
            r.execCommand('copy');
        }
    </script>
    <input value="http://www.sajithmr.com"
     onclick="select_all(this)" name="url" type="text" />

Answer

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;
 }

@korayem: Note that using html input field won't respect line breaks \n and will flatten any text into a single line.

As mentioned by @nikksan in the comments, using textarea will fix the problem as follows:

function copy(text) {
    var input = document.createElement('textarea');
    input.innerHTML = text;
    document.body.appendChild(input);
    input.select();
    var result = document.execCommand('copy');
    document.body.removeChild(input);
    return result;
}
Answer

I have recently written a technical blog post on this very problem (I work at Lucidchart and we recently did an overhaul on our clipboard).

Copying plain text to the clipboard is relatively simple, assuming you want to do it during a system copy event (user presses CtrlC or uses the browser's menu).

var isIe = (navigator.userAgent.toLowerCase().indexOf("msie") != -1 
           || navigator.userAgent.toLowerCase().indexOf("trident") != -1);

document.addEventListener('copy', function(e) {
    var textToPutOnClipboard = "This is some text";
    if (isIe) {
        window.clipboardData.setData('Text', textToPutOnClipboard);    
    } else {
        e.clipboardData.setData('text/plain', textToPutOnClipboard);
    }
    e.preventDefault();
});

Putting text on the clipboard not during a system copy event is much more difficult. It looks like some of these other answers reference ways to do it via Flash, which is the only cross-browser way to do it (so far as I understand).

Other than that, there are some options on a browser-by-browser basis.

This is the most simple in IE, where you can access the clipboardData object at anytime from JavaScript via:

window.clipboardData

(When you attempt to do this outside of a system cut, copy, or paste event, however, IE will prompt the user to grant the web application clipboard permission.)

In Chrome, you can create a Chrome extension that will give you clipboard permissions (this is what we do for Lucidchart). Then for users with your extension installed you'll just need to fire the system event yourself:

document.execCommand('copy');

It looks like Firefox has some options that allow users to grant permissions to certain sites to access the clipboard, but I haven't tried any of these personally.

Answer

clipboard.js is a small, non-Flash, utility that allows copying of text or HTML data to the clipboard. It's very easy to use, just include the .js and use something like this:

<button id='markup-copy'>Copy Button</button>

<script>
document.getElementById('markup-copy').addEventListener('click', function() {
  clipboard.copy({
    'text/plain': 'Markup text. Paste me into a rich text editor.',
    'text/html': '<i>here</i> is some <b>rich text</b>'
  }).then(
    function(){console.log('success'); },
    function(err){console.log('failure', err);
  });

});
</script>

clipboard.js is also on GitHub.

Note: This has been deprecated now. Migrate to here.

Answer

ZeroClipboard is the best cross-browser solution I've found:

<div id="copy" data-clipboard-text="Copy Me!">Click to copy</div>    
<script src="ZeroClipboard.js"></script>
<script>
  var clip = new ZeroClipboard( document.getElementById('copy') );
</script>

If you need non-flash support for iOS you just add a fall-back:

clip.on( 'noflash', function ( client, args ) {
    $("#copy").click(function(){            
        var txt = $(this).attr('data-clipboard-text');
        prompt ("Copy link, then click OK.", txt);
    });
});  

http://zeroclipboard.org/

https://github.com/zeroclipboard/ZeroClipboard

Answer

From one of the projects I've been working on, a jQuery copy-to-clipboard plugin that utilizes the Zero Clipboard library.

It is easier to use than the native Zero Clipboard plugin if you're a heavy jQuery user.

Answer

In 2018, here's how you can go about it:

async copySomething(text?) {
  try {
    const toCopy = text || location.href;
    await navigator.clipboard.writeText(toCopy);
    console.log('Text or Page URL copied');
  }
  catch (err) {
    console.error('Failed to copy: ', err);
  }
}

It is used in my Angular 6+ code like so:

<button mat-menu-item (click)="copySomething()">
    <span>Copy link</span>
</button>

If I pass in a string, it copies it. If nothing, it copies the page's URL.

More gymnastics to the clipboard stuff can be done too. See more information here:

Unblocking Clipboard Access

Answer

I found the following solution:

On key down handler creates "pre" tag. We set the content to copy to this tag, then make a selection on this tag and return true in handler. This calls standard handler of chrome and copies selected text.

And if you need you may be set the timeout for function for restoring previous selection. My implementation on Mootools:

   function EnybyClipboard() {
     this.saveSelection = false;
     this.callback = false;
     this.pastedText = false;

     this.restoreSelection = function() {
       if (this.saveSelection) {
         window.getSelection().removeAllRanges();
         for (var i = 0; i < this.saveSelection.length; i++) {
           window.getSelection().addRange(this.saveSelection[i]);
         }
         this.saveSelection = false;
       }
     };

     this.copyText = function(text) {
       var div = $('special_copy');
       if (!div) {
         div = new Element('pre', {
           'id': 'special_copy',
           'style': 'opacity: 0;position: absolute;top: -10000px;right: 0;'
         });
         div.injectInside(document.body);
       }
       div.set('text', text);
       if (document.createRange) {
         var rng = document.createRange();
         rng.selectNodeContents(div);
         this.saveSelection = [];
         var selection = window.getSelection();
         for (var i = 0; i < selection.rangeCount; i++) {
           this.saveSelection[i] = selection.getRangeAt(i);
         }
         window.getSelection().removeAllRanges();
         window.getSelection().addRange(rng);
         setTimeout(this.restoreSelection.bind(this), 100);
       } else return alert('Copy not work. :(');
     };

     this.getPastedText = function() {
       if (!this.pastedText) alert('Nothing to paste. :(');
       return this.pastedText;
     };

     this.pasteText = function(callback) {
       var div = $('special_paste');
       if (!div) {
         div = new Element('textarea', {
           'id': 'special_paste',
           'style': 'opacity: 0;position: absolute;top: -10000px;right: 0;'
         });
         div.injectInside(document.body);
         div.addEvent('keyup', function() {
           if (this.callback) {
             this.pastedText = $('special_paste').get('value');
             this.callback.call(null, this.pastedText);
             this.callback = false;
             this.pastedText = false;
             setTimeout(this.restoreSelection.bind(this), 100);
           }
         }.bind(this));
       }
       div.set('value', '');
       if (document.createRange) {
         var rng = document.createRange();
         rng.selectNodeContents(div);
         this.saveSelection = [];
         var selection = window.getSelection();
         for (var i = 0; i < selection.rangeCount; i++) {
           this.saveSelection[i] = selection.getRangeAt(i);
         }
         window.getSelection().removeAllRanges();
         window.getSelection().addRange(rng);
         div.focus();
         this.callback = callback;
       } else return alert('Fail to paste. :(');
     };
   }

Usage:

enyby_clip = new EnybyClipboard(); //init 

enyby_clip.copyText('some_text'); // place this in CTRL+C handler and return true;

enyby_clip.pasteText(function callback(pasted_text) {
        alert(pasted_text);
}); // place this in CTRL+V handler and return true;

On paste it creates textarea and works the same way.

PS may be this solution can be used for creating fully cross-browser solution without flash. Its works in FF and Chrome.

Answer

Since Chrome 42+ and Firefox 41+ now support the document.execCommand('copy') command. So I created a couple of functions for a cross-browser copy-to-clipboard ability using a combination of Tim Down's old answer and Google Developer's answer:

function selectElementContents(el) {
    // Copy textarea, pre, div, etc.
    if (document.body.createTextRange) {
        // IE
        var textRange = document.body.createTextRange();
        textRange.moveToElementText(el);
        textRange.select();
        textRange.execCommand("Copy");
    } 
    else if (window.getSelection && document.createRange) {
        // Non-Internet Explorer
        var range = document.createRange();
        range.selectNodeContents(el);
        var sel = window.getSelection();
        sel.removeAllRanges();
        sel.addRange(range);
        try {
            var successful = document.execCommand('copy');
            var msg = successful ? 'successful' : 'unsuccessful';
            console.log('Copy command was ' + msg);
        }
        catch (err) {
            console.log('Oops, unable to copy');
        }
    }
} // end function selectElementContents(el)

function make_copy_button(el) {
    var copy_btn = document.createElement('input');
    copy_btn.type = "button";
    el.parentNode.insertBefore(copy_btn, el.nextSibling);
    copy_btn.onclick = function() {
        selectElementContents(el);
    };

    if (document.queryCommandSupported("copy") || parseInt(navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./)[2]) >= 42) {
        // Copy works with Internet Explorer 4+, Chrome 42+, Firefox 41+, Opera 29+
        copy_btn.value = "Copy to Clipboard";
    }
    else {
        // Select only for Safari and older Chrome, Firefox and Opera
        copy_btn.value = "Select All (then press Ctrl + C to Copy)";
    }
}
/* Note: document.queryCommandSupported("copy") should return "true" on browsers that support copy
    but there was a bug in Chrome versions 42 to 47 that makes it return "false".  So in those
    versions of Chrome feature detection does not work!
    See https://code.google.com/p/chromium/issues/detail?id=476508
*/

make_copy_button(document.getElementById("markup"));
<pre id="markup">
  Text that can be copied or selected with cross browser support.
</pre>

Answer

I use this very successfully (without jQuery or any other framework).

function copyToClp(txt){
    txt = document.createTextNode(txt);
    var m = document;
    var w = window;
    var b = m.body;
    b.appendChild(txt);
    if (b.createTextRange) {
        var d = b.createTextRange();
        d.moveToElementText(txt);
        d.select();
        m.execCommand('copy');
    } 
    else {
        var d = m.createRange();
        var g = w.getSelection;
        d.selectNodeContents(txt);
        g().removeAllRanges();
        g().addRange(d);
        m.execCommand('copy');
        g().removeAllRanges();
    }
    txt.remove();
}

Warning

Tabs are converted to spaces (at least in Chrome).

Answer

The other methods will copy plain text to the clipboard. To copy HTML (ie, you can paste results into a WSIWYG editor), you can do the following in IE ONLY. This is is fundamentally different from the other methods, as the browser actually visibly selects the content.

// create an editable DIV and append the HTML content you want copied
var editableDiv = document.createElement("div");
with (editableDiv) {
    contentEditable = true;
}     
editableDiv.appendChild(someContentElement);          

// select the editable content and copy it to the clipboard
var r = document.body.createTextRange();
r.moveToElementText(editableDiv);
r.select();  
r.execCommand("Copy");

// deselect, so the browser doesn't leave the element visibly selected
r.moveToElementText(someHiddenDiv);
r.select();   
Answer

I've put together what I think is the best one.

  • Uses cssText to avoid exceptions in Internet¬†Explorer as opposed to style directly.
  • Restores selection if there was one
  • Sets readonly so keyboard doesn't come up on mobile devices
  • Has a workaround for iOS so that it actually works as it normally blocks execCommand.

Here it is:

const copyToClipboard = (function initClipboardText() {
  const textarea = document.createElement('textarea');

  // Move it off screen.
  textarea.style.cssText = 'position: absolute; left: -99999em';

  // Set to readonly to prevent mobile devices opening a keyboard when
  // text is .select()'ed.
  textarea.setAttribute('readonly', true);

  document.body.appendChild(textarea);

  return function setClipboardText(text) {
    textarea.value = text;

    // Check if there is any content selected previously.
    const selected = document.getSelection().rangeCount > 0 ?
      document.getSelection().getRangeAt(0) : false;

    // iOS Safari blocks programmtic execCommand copying normally, without this hack.
    // https://stackoverflow.com/questions/34045777/copy-to-clipboard-using-javascript-in-ios
    if (navigator.userAgent.match(/ipad|ipod|iphone/i)) {
      const editable = textarea.contentEditable;
      textarea.contentEditable = true;
      const range = document.createRange();
      range.selectNodeContents(textarea);
      const sel = window.getSelection();
      sel.removeAllRanges();
      sel.addRange(range);
      textarea.setSelectionRange(0, 999999);
      textarea.contentEditable = editable;
    }
    else {
      textarea.select();
    }

    try {
      const result = document.execCommand('copy');

      // Restore previous selection.
      if (selected) {
        document.getSelection().removeAllRanges();
        document.getSelection().addRange(selected);
      }

      return result;
    }
    catch (err) {
      console.error(err);
      return false;
    }
  };
})();

Usage: copyToClipboard('some text')

Answer

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.

Answer

  <!DOCTYPE html>

  <style>
    #t {
      width: 1px
      height: 1px
      border: none
    }
    #t:focus {
      outline: none
    }
  </style>

  <script>
    function copy(text) {
      var t = document.getElementById('t')
      t.innerHTML = text
      t.select()
      try {
        var successful = document.execCommand('copy')
        var msg = successful ? 'successfully' : 'unsuccessfully'
        console.log('text coppied ' + msg)
      } catch (err) {
        console.log('Unable to copy text')
      }
      t.innerHTML = ''
    }
  </script>

  <textarea id=t></textarea>

  <button onclick="copy('hello world')">
    Click me
  </button>

Answer

I found the following solution:

I have the text in a hidden input. Because setSelectionRange doesn't work on hidden inputs, I changed temporarily the type to text, copied the text, and then made it hidden again. If you want to copy the text from an element, you can pass it to the function and save its content in the target variable.

jQuery('#copy').on('click', function () {
    copyToClipboard();
});

function copyToClipboard() {
    var target = jQuery('#hidden_text');

    // Make it visible, so can be focused
    target.attr('type', 'text');
    target.focus();
    // Select all the text
    target[0].setSelectionRange(0, target.val().length);

    // Copy the selection
    var succeed;
    try {
        succeed = document.execCommand("copy");
    }
    catch (e) {
        succeed = false;
    }

    // Hide input again
    target.attr('type', 'hidden');

    return succeed;
}
Answer

There are many answers already, however like to add one (jQuery). Works great on any browser, also mobile ones (i.e., prompts about security, but when you accept it just works fine).

function appCopyToClipBoard(sText)
{
    var oText = false,
        bResult = false;
    try
    {
        oText = document.createElement("textarea");
        $(oText).addClass('clipboardCopier').val(sText).insertAfter('body').focus();
        oText.select();
        document.execCommand("Copy");
        bResult = true;
    }
    catch(e) {
    }

    $(oText).remove();
    return bResult;
}

In your code:

if (!appCopyToClipBoard('Hai there! This is copied to the clipboard.'))
{
    alert('Sorry, copy to clipboard failed.');
}
Answer

Copy text from HTML input to the clipboard:

 function myFunction() {
   /* Get the text field */
   var copyText = document.getElementById("myInput");

   /* Select the text field */
   copyText.select();

   /* Copy the text inside the text field */
   document.execCommand("Copy");

   /* Alert the copied text */
   alert("Copied the text: " + copyText.value);
 }
 <!-- The text field -->
 <input type="text" value="Hello Friend" id="myInput">

 <!-- The button used to copy the text -->
<button onclick="myFunction()">Copy text</button>

Note: The document.execCommand() method is not supported in Internet Explorer 9 and earlier.

Source: W3Schools - Copy Text to Clipboard

Answer

In browsers other than IE you need to use a small flash object to manipulate the clipboard, e.g.

Answer

I had the same problem building a custom grid edit from (something like Excel) and compatibility with Excel. I had to support selecting multiple cells, copying and pasting.

Solution: create a textarea where you will be inserting data for the user to copy (for me when the user is selecting cells), set focus on it (for example, when user press Ctrl) and select the whole text.

So, when the user hit Ctrl + C he/she gets copied cells he/she selected. After testing just resizing the textarea to one pixel (I didn't test if it will be working on display:none). It works nicely on all browsers, and it is transparent to the user.

Pasting - you could do same like this (differs on your target) - keep focus on textarea and catch paste events using onpaste (in my project I use textareas in cells to edit).

I can't paste an example (commercial project), but you get the idea.

Answer

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"/>' )
Answer

I have used clipboard.js.

We can get it on npm:

npm install clipboard --save

And also on Bower

bower install clipboard --save

Usage & examples are at https://zenorocha.github.io/clipboard.js/.

Answer

This is an expansion of @Chase's answer, with the advantage that it will work for IMAGE and TABLE elements, not just DIVs on IE9.

if (document.createRange) {
    // IE9 and modern browsers
    var r = document.createRange();
    r.setStartBefore(to_copy);
    r.setEndAfter(to_copy);
    r.selectNode(to_copy);
    var sel = window.getSelection();
    sel.addRange(r);
    document.execCommand('Copy');  // does nothing on FF
} else {
    // IE 8 and earlier.  This stuff won't work on IE9.
    // (unless forced into a backward compatibility mode,
    // or selecting plain divs, not img or table). 
    var r = document.body.createTextRange();
    r.moveToElementText(to_copy);
    r.select()
    r.execCommand('Copy');
}
Answer

It seems I misread the question, but for reference, you can extract a range of the DOM (not to clipboard; compatible with all modern browsers), and combine it with the oncopy and onpaste and onbeforepaste events to get clipboard behaviour. Here's the code to achieve this:

function clipBoard(sCommand) {
  var oRange=contentDocument.createRange();
  oRange.setStart(startNode, startOffset);
  oRange.setEnd(endNode, endOffset);
/* This is where the actual selection happens.
in the above, startNode and endNode are dom nodes defining the beginning 
and end of the "selection" respectively. startOffset and endOffset are 
constants that are defined as follows:

END_TO_END: 2
END_TO_START: 3
NODE_AFTER: 1
NODE_BEFORE: 0
NODE_BEFORE_AND_AFTER: 2
NODE_INSIDE: 3
START_TO_END: 1
START_TO_START: 0

and would be used like oRange.START_TO_END */
      switch(sCommand) {
    case "cut":
          this.oFragment=oRange.extractContents();
      oRange.collapse();
      break;
    case "copy":
      this.oFragment=oRange.cloneContents();
      break;
    case "paste":
      oRange.deleteContents();
      var cloneFragment=this.oFragment.cloneNode(true)
      oRange.insertNode(cloneFragment);
      oRange.collapse();
      break;
  }
}
Answer

My bad. This only works in IE.

Here's yet another way to copy text:

<p>
    <a onclick="window.clipboardData.setData('text', document.getElementById('Test').innerText);">Copy</a>
</p>
Answer

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.

Answer

To copy a selected text ('Text To Copy') to your clipboard, create a Bookmarklet (browser bookmark that executes JavaScript) and execute it (click on it). It will create a temporary textarea.

Code from GitHub:

https://gist.github.com/stefanmaric/2abf96c740191cda3bc7a8b0fc905a7d

(function (text) {
  var node = document.createElement('textarea');
  var selection = document.getSelection();

  node.textContent = text;
  document.body.appendChild(node);

  selection.removeAllRanges();
  node.select();
  document.execCommand('copy');

  selection.removeAllRanges();
  document.body.removeChild(node);
})('Text To Copy');
Answer

I like this one:

<input onclick="this.select();" type='text' value='copy me' />

If a user doesn't know how to copy text in their OS, then it's likely they don't know how to paste either. So just have it automatically selected, leaving the rest to the user.

Answer

    $("td").click(function (e) {
        var clickedCell = $(e.target).closest("td");
        navigator.clipboard.writeText(clickedCell.text());
        alert(clickedCell.text());
    });
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr>
<td>First<td>
</tr>
<tr>
<td>Second<td>
</tr>
<tr>
<td>Third<td>
</tr>
<tr>
<td>Fourth<td>
</tr>
</table>

I've read all the answers, as of June 1st, 2020, I've beeen struggling to solve this when I finally found documentation:

$("td").click(function (e) {
    var clickedCell = $(e.target).closest("td");
    navigator.clipboard.writeText(clickedCell.text());
});

It will write the clicked cell text to the browser clipboard.

You can change the selectors "td" for anything you want, you can add console.log for debugging and/or alert functions.

Here is documentation: https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/writeText

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us Javascript

©2020 All rights reserved.