Pure JavaScript copy to clipboard function

I wanted to add a copy button to code blocks when they’re hovered (or focused for mobile support) so the code can be easily copied.

In the past you had to use nasty hacks using Flash to do this. Luckily there is now the simpler document.execCommand(‘copy’) method which makes everything a lot easier!

I’ve created a small copyToClipboard function which will copy the text of any string or node passed to it without losing the current selection.

window.copyToClipboard = function (node) {
  // Skip IE < 9 which uses TextRange instead of Range
  if (!window.getSelection) {
    return false;
  }

  var doc = document;
  var result = false;
  var ranges = [];
  var selection = window.getSelection();

  if (typeof node === 'string' || node instanceof String) {
    var container = doc.createElement('div');
    container.appendChild(doc.createTextNode(node));
    
    doc.body.appendChild(container);
    result = copyToClipboard(container);
    doc.body.removeChild(container); 

    return result;
  }

  for(var i = 0; i < selection.rangeCount; i++) {
    ranges[i] = selection.getRangeAt(i);
  }

  selection.selectAllChildren(node);

  try {  
    result = doc.execCommand('copy');
  } catch(err) { }

  // Restore previous selection if any
  selection.removeAllRanges();
  ranges.forEach(selection.addRange.bind(selection));

  return result;
};

Browser compatibility

The code works in IE 9+ and all other major browsers. Support could be added for older versions of IE but since Microsoft no longer supports them I didn’t think it was worth doing for this.

Demo

<p id="copy-demo" >
  The <span>contents</span> of this paragraph will be copied!
</p>

<button onclick="copyToClipboard(document.getElementById('copy-demo'));">Click me</button>
<button onclick="copyToClipboard('Hello World!');">Copy string</button>

The contents of this paragraph will be copied!

Comments