JavaScript
Article
By Craig Buckler

Roll Your Own Copy to Clipboard Feature in 20 Lines of JavaScript

By Craig Buckler

Using the OS clipboard is a basic IT skill. As a developer, you’ve learned that tab, Ctrl/Cmd+A, Ctrl/Cmd+C followed by Ctrl/Cmd+V will highlight, copy and paste in an instant.

Life is less easy for regular users. Even if a user knows what the clipboard is, those with 20:20 vision and cat-like reflexes can struggle to highlight the exact text they want. The copying process is rarely intuitive if they don’t know keyboard shortcuts, can’t see the hidden browser Edit menu, have never used a right-click menu or don’t know about long-hold options on touch-screens.

Perhaps we could help everyone by offering one-click “copy to clipboard” buttons? That would be useful for even the quickest keyboard-happy power user!

Clipboard Security

A few years ago it was impossible for browsers to directly use the clipboard. Developers had to resort to Flash applets to provide basic functionality.

The clipboard seems innocuous but imagine what could happen if a browser was able to view and manipulate the content at will. It would be possible for scripts (including third-party ones) to peek at the text and post passwords, sensitive information or even whole documents to a remote server.

Today, basic clipboard integration is possible but there are limitations:

  1. Most browsers support the clipboard but forget Safari on Mac and iOS.
  2. Support varies across browsers and some features are incomplete or buggy.
  3. The user must initiate an event such as clicking a mouse button or pressing the keyboard. A script cannot arbitrarily use the clipboard at any time.

document.execCommand()

The key method is document.execCommand() which can be passed 'cut', 'copy' or 'paste'. We’ll concentrate on document.execCommand('copy') since it’s the most useful option.

Before using it, we should check whether the browser supports the command copying using either document.queryCommandSupported('copy'); or document.queryCommandEnabled('copy'); (yes, that’s two methods which do the same thing). Unfortunately, both return false in Chrome even though it’s supported. We could check the availability of document.execCommand but the most viable option is to wrap document.execCommand('copy') in a try-catch block.

Next, what should we allow the user to copy? Our script must highlight text and all browsers permit textual input and textarea fields to be selected using the select() method. Firefox and Chrome/Opera also support document.createRange which allows text to be selected from any element, e.g.

// select text in #myelement node
var
  myelement = document.getElementById('#myelement'),
  range = document.createRange();

range.selectNode(myelement);
window.getSelection().addRange(range);

However, this isn’t supported in IE/Edge.

--ADVERTISEMENT--

clipboard.js

If you’ve given up all hope of implementing a robust cross-browser clipboard solution, clipboard.js can ease the pain. It has several options such as HTML5 data attributes which identify an activation trigger and which element will be copied, e.g.

<input id="copyme" value="text in this field will be copied" />
<button data-clipboard-target="#copyme">copy</button>

Roll Your Own

clipboard.js is a mere 2Kb but we can implement a solution in less than twenty lines of code if we’re happy to accept the following criteria:

  • only appropriate form fields can be copied
  • it’ll fail in some browsers (I’m looking at you Safari) but we can highlight the input text and show a message advising the user to press Ctrl/Cmd + C.

Like clipboard.js, we’ll create an activation trigger button which has a data attribute (data-copytarget) pointing at an element to copy (#website):

<input type="text" id="website" value="http://www.sitepoint.com/" />
<button data-copytarget="#website">copy</button>

A self-executing function can attach a click event handler which parses any data-copytarget attributes, selects the field’s text and runs document.execCommand('copy'). If this fails, the text remains selected and the advise alert box is displayed:

(function() {

  'use strict';

  // click events
  document.body.addEventListener('click', copy, true);

  // event handler
  function copy(e) {

    // find target element
    var
      t = e.target,
      c = t.dataset.copytarget,
      inp = (c ? document.querySelector(c) : null);

    // is element selectable?
    if (inp && inp.select) {

      // select text
      inp.select();

      try {
        // copy text
        document.execCommand('copy');
        inp.blur();
      }
      catch (err) {
        alert('please press Ctrl/Cmd+C to copy');
      }

    }

  }

})();

Demonstration:

See the Pen JavaScript clipboard integration by SitePoint (@SitePoint) on CodePen.

This demonstration has styling and a “copied” animation which takes it over twenty lines of code but that’s optional.

Summary:

  1. Use the .select() method to select the contents of the form element you wish to copy
  2. Call the document.execCommand("copy") method
  3. Call the .blur() method to remove focus from the form element
  4. Wrap steps 2 & 3 in a try catch block to cater for non-compliant browsers

Other Uses

You may be able to devise other novel clipboard integration features. For example, when hovering your mouse over any card in Trello.com, you can press Ctrl/Cmd+C and that card’s URL is copied to the clipboard. In the background, the application creates a hidden form element containing the URL then selects and copies it. Useful and clever — although I suspect few users know about the feature!

Please share your ideas with others below.

Recommended
Sponsors
The most important and interesting stories in tech. Straight to your inbox, daily. Get Versioning.
Login or Create Account to Comment
Login Create Account