Search code examples
javascripthtmljquerygetselection

Copy selection to clipboard only works once


I have this JS code that you can just pass an ID of an element and it will copy the text from that element. However, when I have multiple snippets on a page and want to copy more than one it won't work.

On first page load I can copy one snippet, every snippet after that is not copied correctly, do I have to clear the clipboard from the first snippet?

function copy_snippet(snippet) {
  if (document.selection) {
    var range = document.body.createTextRange();
    range.moveToElementText(document.getElementById(snippet));
    range.select().createTextRange();
    document.execCommand("copy");
  } else if (window.getSelection) {
    var range = document.createRange();
    range.selectNode(document.getElementById(snippet));
    window.getSelection().addRange(range);
    document.execCommand("copy");
  }
}
<div id="1">
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam et tempus lacus, at congue augue. Vivamus nisl diam, ornare non justo vel, pulvinar gravida magna. Nullam posuere pharetra felis, sit amet viverra ex bibendum ut. Cras hendrerit tempor metus
  ut interdum. Suspendisse potenti. Etiam mi nunc, lacinia non justo vel, eleifend lobortis lectus. Morbi nulla diam, volutpat quis mauris ut, ultrices venenatis massa.
</div>
<button onclick="copy_snippet('1');">Copy</button>

<br /><br />

<div id="2">
  Vestibulum est arcu, porttitor a leo in, rhoncus mattis elit. In hac habitasse platea dictumst. Praesent vitae felis vitae risus ornare mattis. Maecenas ac condimentum lorem. Proin ornare nisi non sapien accumsan, quis suscipit est pellentesque. Sed enim
  purus, auctor sit amet tincidunt id, convallis a eros. Aenean a rhoncus orci. Pellentesque consequat ligula tincidunt semper varius.
</div>
<button onclick="copy_snippet('2');">Copy</button>


Solution

  • It's not that you have to clear the clipboard, but that you need to clear the selection. This is covered in this answer:

    Clear Text Selection with JavaScript

    I've made the change to your snippet and it's working (for me at least, on chrome)

    function copy_snippet(snippet){
    
        if(document.selection){
            document.selection.empty();
            var range = document.body.createTextRange();
            range.moveToElementText(document.getElementById(snippet));
            range.select().createTextRange();
            document.execCommand("copy");
        }else if(window.getSelection){
            if (window.getSelection().empty) {  // Chrome
              window.getSelection().empty();
            } else if (window.getSelection().removeAllRanges) {  // Firefox
              window.getSelection().removeAllRanges();
            }
            var range = document.createRange();
            range.selectNode(document.getElementById(snippet));
            window.getSelection().addRange(range);
            document.execCommand("copy");
        }
    }
    <div id="1">
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam et tempus lacus, at congue augue. Vivamus nisl diam, ornare non justo vel, pulvinar gravida magna. Nullam posuere pharetra felis, sit amet viverra ex bibendum ut. Cras hendrerit tempor metus ut interdum. Suspendisse potenti. Etiam mi nunc, lacinia non justo vel, eleifend lobortis lectus. Morbi nulla diam, volutpat quis mauris ut, ultrices venenatis massa.
    </div>
    <button onclick="copy_snippet('1');">Copy</button>
    
    <br /><br />
    
    <div id="2">
    Vestibulum est arcu, porttitor a leo in, rhoncus mattis elit. In hac habitasse platea dictumst. Praesent vitae felis vitae risus ornare mattis. Maecenas ac condimentum lorem. Proin ornare nisi non sapien accumsan, quis suscipit est pellentesque. Sed enim purus, auctor sit amet tincidunt id, convallis a eros. Aenean a rhoncus orci. Pellentesque consequat ligula tincidunt semper varius.
    </div>
    <button onclick="copy_snippet('2');">Copy</button>