javascripthtmlclipboard

Javascript - Copy to clipboard without concrete Id in HTML tag


On an HTML page, there should be several snippets in code tags. It should be possible to copy the code to the clipboard via a button click. I have working code for one code tag for which the reference is made using an ID. However, how to change the JavaScript code so that the copying is not dependent on a manually predefined ID in the code tag. When hitting the copy to clipboard button for a certain code snippet, it should automatically copy the content of the intended code block - while having many other code tags with the same copy to clipboard button on the page. My example shows one code block with a predefined ID. How to avoid the ID in the JS code to make it work independently?

function copy_text() {
  const str = document.getElementById("copy_code").innerText; const el = document.createElement("textarea");
  el.value = str; el.setAttribute("readonly", ""); el.style.position = "absolute";
  el.style.left = '-9999px'; document.body.appendChild(el);
  el.select(); document.execCommand("copy"); document.body.removeChild(el);
};
<code id="copy_code">some code 1<br>some code 2<br>some code 3</code>
<button onclick="copy_text()">Copy to clipboard</button>


Solution

  • You can pass this to the copy_text() method call so your function knows exactly which button triggered the onclick event. You can then get the elements of it's parent container, assuming each code block and it's button are inside inside a parent container:

    function copy_text(item) {
      const str = item.parentNode.querySelector('code').innerText;
      const el = document.createElement("textarea");
      el.value = str;
      el.setAttribute("readonly", "");
      el.style.position = "absolute";
      el.style.left = '-9999px';
      document.body.appendChild(el);
      el.select(); document.execCommand("copy");
      document.body.removeChild(el);
    };
    <div>
      <code>1<br>2<br>3</code>
      <button onclick="copy_text(this)">copy</button>
    </div>
    
    <div>
      <code>4<br>5<br>6</code>
      <button onclick="copy_text(this)">copy</button>
    </div>

    In case if each code block and it's button are not inside some parent container and are entered in HTML exactly like in the question you can use

    const str = item.previousElementSibling.innerText;
    

    instead of

    const str = item.parentNode.querySelector('code').innerText;
    

    function copy_text(item) {
      const str = item.previousElementSibling.innerText;
      const el = document.createElement("textarea");
      el.value = str;
      el.setAttribute("readonly", "");
      el.style.position = "absolute";
      el.style.left = '-9999px';
      document.body.appendChild(el);
      el.select(); document.execCommand("copy");
      document.body.removeChild(el);
    };
    <code>1<br>2<br>3</code>
    <button onclick="copy_text(this)">copy</button>
    <br>
    <code>4<br>5<br>6</code>
    <button onclick="copy_text(this)">copy</button>