Copy the text to the clipboard by JS and HTML

How to copy text to clipboard ? there is a part of example about the shorten the URL as following:

Example HTML

<div class="container mt-2" style="width: 400px;">
  <div class="row mt-2 justify-content-center">
    <h3 class="mb-1">Success! PLease use this link:</h3>
    <input class="text-center mt-2" id="shorten-url" value="{{shortenUrl}}" disabled>
    <div class="row justify-content-center" id="btn-group">
      <button type="submit" style="width: 100px;" class="btn btn-success mt-4" id="copy-button" onclick="copyText()">
        Copy to clipboard</button>
      <a href="/" class="btn btn-primary ms-3 mt-4 pt-3" style="width: 100px;">Back</a>
    </div>
  </div>
</div>

Example JS

 <script>
    function copyText() {
      let copyInput = document.getElementById('shorten-url')
      let copied = document.getElementById('btn-group')

      copyInput.select()

      navigator.clipboard.writeText(copyInput.value)
      copied.innerHTML = `
      <button type="submit" style="width: 100px;" class="btn btn-danger mt-4" id="copy-button" onclick="copyText()">
        Already copied</button>
      <a href="/" class="btn btn-primary ms-3 mt-4 pt-3" style="width: 100px;">Back</a>
      `
    }
  </script>

In the early, developers used the [execCommond()](https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand) to make this feature. Here is the explanation from MDN:

Deprecated: This feature is no longer recommended. Though some browsers might still support it, it may have already been removed from the relevant web standards, may be in the process of being dropped, or may only be kept for compatibility purposes. Avoid using it, and update existing code if possible; see the compatibility table at the bottom of this page to guide your decision. Be aware that this feature may cease to work at any time.

According to the W3school, I use the writeText() to do it. First, make a <button> with onclick event and write a function in <script>. To get the value of <input>, i use the select() to get all the content. Then, navigator.clipboard.writeText() will put it in the clipboard.

However, there is one thing have to pay attention. If you want to use alert(), it will have an error cause the clipboard API is asynchronous. it will show the window of alert before finishing the copy process and error will show that:

Uncaught (in promise) DOMException: Document is not focused.

You have to use async/await to finish the process of clipboard then show the alert. The example is as following:

 <script>
    async function copyText() {
      let copyInput = document.getElementById('shorten-url')
      let copied = document.getElementById('btn-group')

      copyInput.select()

      await navigator.clipboard.writeText(copyInput.value)

      copied.innerHTML = `
      <button type="submit" style="width: 100px;" class="btn btn-danger mt-4" id="copy-button" onclick="copyText()">
        Already copied</button>
      <a href="/" class="btn btn-primary ms-3 mt-4 pt-3" style="width: 100px;">Back</a>
      `
    }
  </script>

Ref:

https://lichi-chen.medium.com/使用-js-複製貼上剪貼簿發生-uncaught-in-promise-domexception-document-is-not-focused-e43b24362a82