Copy text to clipboard using Javascript on desktop and mobile browsers (including iOS)

Copy text from an input using JavaScript on mobile iOS devices using a range to create a selection.

by wethrift

HTML

<script src="https://www.wethrift.com"></script>
<script src="https://jsfiddle.net/wethrift/za08qpy3/30/"></script>
<html>

  <head>
    <link href="https://fonts.googleapis.com/css?family=Lato:300,400" rel="stylesheet">
  </head>

  <body>
    <section class="demo">
      <!-- here's the HTML you'll need -->
      <input id="text" value="text to copy" />
      <button onclick="copyText()">
      Copy text
    </button>
    </section>
    <section class="explanation">
      <p>
        At <a href="https://www.wethrift.com">Wethrift.com</a> we use 'input' and 'button' elements to let users easily copy content from our pages without having to right click or tap-to-select page text.
      </p>
      <p>
        Unfortunately, Mobile Safari on iOS does not handle an input's .select() method, so we need to create and use a <a href="https://developer.mozilla.org/en-US/docs/Web/API/Range">range</a> to select and copy text from the page for iOS devices.
      </p>
    </section>
    <section class="logo">
      <a href="https://www.wethrift.com"><img src="//www.gravatar.com/avatar/cdc263061cc1f696c996618a6458717c/?default=&s=120"/></a>
    </section>

  </body>

</html>

CSS

section {
  font-family: lato, sans-serif;
  padding: 10px;
}

.demo {
  padding-top: 20px;
  text-align: center;
}

input,
button {
  font-family: lato, sans-serif;
  padding: 5px 10px;
  font-size: 18px;
  border-radius: 5px;
  border: 1px solid #CBCBCB;
}

p {
  font-family: lato, sans-serif;
  font-weight: 300;
}

a {
  color: inherit;
}

.logo {
  text-align: center;
}

.logo img {
  height: 75px;
  border-radius: 50%;
}

JavaScript

function copyText() {
  var input = document.querySelector('#text');

  if (navigator.userAgent.match(/ipad|ipod|iphone/i)) {
    // handle iOS devices
    input.contenteditable = true;
    input.readonly = false;

    var range = document.createRange();
    range.selectNodeContents(input);

    var selection = window.getSelection();
    selection.removeAllRanges();
    selection.addRange(range);
    input.setSelectionRange(0, 999999);
  } else {
    // other devices are easy
    input.select()
  }
  document.execCommand('copy');
}