105

Here is my code for when the user clicks on this button:

<button id="button1">Click to copy</button>

How do I copy the text inside this div?

<div id="div1">Text To Copy</div>
Edric
  • 24,639
  • 13
  • 81
  • 91
Alex
  • 1,451
  • 5
  • 15
  • 16

11 Answers11

140

I tried the solution proposed above. But it was not cross-browser enough. I really needed ie11 to work. After trying I got to:

    <html>
        <body>
            <div id="a" onclick="copyDivToClipboard()"> Click to copy </div>
            <script>
                function copyDivToClipboard() {
                    var range = document.createRange();
                    range.selectNode(document.getElementById("a"));
                    window.getSelection().removeAllRanges(); // clear current selection
                    window.getSelection().addRange(range); // to select text
                    document.execCommand("copy");
                    window.getSelection().removeAllRanges();// to deselect
                }
            </script>
        </body>
    </html>

Tested with firefox 64, Chrome 71, Opera 57, ie11(11.472.17134.0), edge( EdgeHTML 17.17134)

Update March 27th, 2019.

For some reason document.createRange() didn't work before with ie11. But now properly returns a Range object. So is better to use that, rather than document.getSelection().getRangeAt(0).

J. García
  • 1,859
  • 1
  • 12
  • 13
  • 7
    This should be the top answer in this thread. After several hours of finding one workable solution, this finally worked for me. Thanks. :-) – Himanshu Aggarwal Mar 12 '19 at 14:41
  • 1
    Tip: add another `window.getSelection().removeAllRanges();` after the copy command to deselect the content after it is copied. – stardust4891 Mar 26 '19 at 00:32
  • Sure, let's add that to the answer. – J. García Mar 27 '19 at 09:44
  • This is simplified example of using `Range` based selections, it doesn't intend to cover all corner cases. And is mainly showcasing one of the ways to use the Range class. Can you be more specific or post another question with your exact use case? I have myself used `Range` based `Selection`s with multiple `divs`/`element`s . I would highly advise to check on the `Range` API and see if any of the other functions this provides would help. – J. García Sep 07 '20 at 06:14
  • @FarhanBinAmin check `Range.setStart()` and `Range.setEnd()`. and use those instead of `Range.selectNode()` – J. García Sep 07 '20 at 06:24
  • this works fine in 2022 – Vinicius Feb 28 '22 at 13:58
  • Note that Range selection will not work if the element you are targeting is hidden with `display:none;`. – squarecandy Oct 01 '22 at 16:09
102

Both examples work like a charm :)

  1. JAVASCRIPT:

    function CopyToClipboard(containerid) {
      if (document.selection) {
        var range = document.body.createTextRange();
        range.moveToElementText(document.getElementById(containerid));
        range.select().createTextRange();
        document.execCommand("copy");
      } else if (window.getSelection) {
        var range = document.createRange();
        range.selectNode(document.getElementById(containerid));
        window.getSelection().addRange(range);
        document.execCommand("copy");
        alert("Text has been copied, now paste in the text-area")
      }
    }
    <button id="button1" onclick="CopyToClipboard('div1')">Click to copy</button>
    <br /><br />
    <div id="div1">Text To Copy </div>
    <br />
    <textarea placeholder="Press ctrl+v to Paste the copied text" rows="5" cols="20"></textarea>
  2. JQUERY (relies on Adobe Flash): https://paulund.co.uk/jquery-copy-to-clipboard

Slbox
  • 10,957
  • 15
  • 54
  • 106
Eldho NewAge
  • 1,313
  • 3
  • 13
  • 17
  • 8
    Just to add to this answer, there is a neat plugin I've used a couple of times that can handle this: https://clipboardjs.com/ – Aaron Lavers Apr 15 '16 at 06:55
  • 15
    1st One Is not Working – Alex Apr 15 '16 at 07:07
  • 2
    Please Tell Me How First Example Would Work – Alex Apr 15 '16 at 07:13
  • I have edited the answer in detail. This will work like a charm :) – Eldho NewAge Apr 15 '16 at 07:26
  • 2
    And I Have A Question, Will This Work On All Browser? – Alex Apr 15 '16 at 08:08
  • 2
    I hope it will do. Checked in firefox and chrome. – Eldho NewAge Apr 15 '16 at 12:15
  • 1
    Make sure the ID on `getElementById` is between double quotes or it won't work. – Vinny Jan 24 '17 at 22:36
  • containerid is a dynamic varialbe, so should not put any double quotes. I mean, document.getElementById("containerid") is a wrong statement here.. – Eldho NewAge May 12 '17 at 10:43
  • Hi, I tried to applied this code to copy content within
    element. It worked well pc. But i tried with Iphone it can copy but all the newline will be removed. May I know how to preserve line break ?
    – Jaden Ng Jun 03 '18 at 07:51
  • 4
    Before call window.getSelection().addRange(range), call this method window.getSelection().removeAllRanges() – yondoo Jul 29 '18 at 09:25
  • probably late answer but, i think it would better to use `const` instead of `var` because `var` is hoisted at the top of the function and `const` is block scoped. `var` can cause some errors and `const` will same memory as well – iLiA Nov 23 '19 at 17:21
  • @AaronLavers your solution does not handle `div` elements. It seems to require `input` elements. – Slbox May 16 '20 at 20:38
  • @Slbox it doesn't require inputs, it can create the input if needed (to the detriment of focus-trapping modals) – Ryan Leach May 22 '21 at 05:39
  • If you need to create an input, whatever the method, then it requires inputs I'd say. – Slbox May 22 '21 at 19:16
  • it works some time and some times it does not work :( – sohail amar Jul 06 '21 at 11:03
  • Note, it copies any selected text, not just selected in `div1` element. So, if you highlight text in textarea it will copy it too. – vanowm Sep 24 '22 at 14:22
24

The accepted answer does not work when you have multiple items to copy, and each with a separate "copy to clipboard" button. After clicking one button, the others will not work.

To make them work, I added some code to the accepted answer's function to clear text selections before doing a new one:

function CopyToClipboard(containerid) {
    if (window.getSelection) {
        if (window.getSelection().empty) { // Chrome
            window.getSelection().empty();
        } else if (window.getSelection().removeAllRanges) { // Firefox
            window.getSelection().removeAllRanges();
        }
    } else if (document.selection) { // IE?
        document.selection.empty();
    }

    if (document.selection) {
        var range = document.body.createTextRange();
        range.moveToElementText(document.getElementById(containerid));
        range.select().createTextRange();
        document.execCommand("copy");
    } else if (window.getSelection) {
        var range = document.createRange();
        range.selectNode(document.getElementById(containerid));
        window.getSelection().addRange(range);
        document.execCommand("copy");
    }
}
romin21
  • 1,532
  • 1
  • 14
  • 35
10

I was getting selectNode() param 1 is not of type node error.

changed the code to this and its working. (for chrome)

function copy_data(containerid) {
  var range = document.createRange();
  range.selectNode(containerid); //changed here
  window.getSelection().removeAllRanges(); 
  window.getSelection().addRange(range); 
  document.execCommand("copy");
  window.getSelection().removeAllRanges();
  alert("data copied");
}
<div id="select_txt">This will be copied to clipboard!</div>
<button type="button" onclick="copy_data(select_txt)">copy</button>
<br>
<hr>
<p>Try paste it here after copying</p>
<textarea></textarea>
Arun Tom
  • 789
  • 6
  • 8
6

This solution add the deselection of the text after the copy to the clipboard:

function copyDivToClipboard(elem) {
    var range = document.createRange();
    range.selectNode(document.getElementById(elem));
    window.getSelection().removeAllRanges();
    window.getSelection().addRange(range);
    document.execCommand("copy");
    window.getSelection().removeAllRanges();
}
loretoparisi
  • 15,724
  • 11
  • 102
  • 146
5
<div id='myInputF2'> YES ITS DIV TEXT TO COPY  </div>

<script>

    function myFunctionF2()  {
        str = document.getElementById('myInputF2').innerHTML;
        const el = document.createElement('textarea');
        el.value = str;
        document.body.appendChild(el);
        el.select();
        document.execCommand('copy');
        document.body.removeChild(el);
        alert('Copied the text:' + el.value);
    };
</script>

more info: https://hackernoon.com/copying-text-to-clipboard-with-javascript-df4d4988697f

OsowoIAM
  • 67
  • 1
  • 4
4

Here you can see code which works on different browsers, including iOS.

const copyToClipboard = (id) => {
  var r = document.createRange();
  r.selectNode(document.getElementById(id));
  window.getSelection().removeAllRanges();
  window.getSelection().addRange(r);
  document.execCommand("copy");
  window.getSelection().removeAllRanges();
};

const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;

const copyIOS = (id) => {
  const text = document.getElementById(id).innerHTML;

  if (!navigator.clipboard) {
    const textarea = document.createElement("textarea");

    textarea.value = text;
    textarea.style.fontSize = "20px";
    document.body.appendChild(textarea);

    const range = document.createRange();
    range.selectNodeContents(textarea);

    const selection = window.getSelection();
    selection.removeAllRanges();
    selection.addRange(range);
    textarea.setSelectionRange(0, 999999);

    document.execCommand("copy");

    document.body.removeChild(textarea);
  }

  navigator.clipboard.writeText(text);
};

const copyTextById = (id) => {
  if (isIOS) {
    return copyIOS(id);
  }
  copyToClipboard(id);
};

window.copyTextById = copyTextById
<div id="text">Text which you will copy</div>

<button onclick="copyTextById('text')">Click me</button>
isherwood
  • 58,414
  • 16
  • 114
  • 157
Andrey Radkevich
  • 3,012
  • 5
  • 25
  • 57
2

Adding the link as an Answer to draw more attention to Aaron Lavers' comment below the first answer.

This works like a charm - http://clipboardjs.com. Just add the clipboard.js or min file. While initiating, use the class which has the html component to be clicked and just pass the id of the component with the content to be copied, to the click element.

Aparna
  • 753
  • 6
  • 10
2

Made a modification to the solutions, so it will work with multiple divs based on class instead of specific IDs. For example, if you have multiple blocks of code. This assumes that the div class is set to "code".

<script>
        $( document ).ready(function() {
            $(".code").click(function(event){
                var range = document.createRange();
                range.selectNode(this);
                window.getSelection().removeAllRanges(); // clear current selection
                window.getSelection().addRange(range); // to select text
                document.execCommand("copy");
                window.getSelection().removeAllRanges();// to deselect
            });
        });
    </script>
2

The solutions above do not work for the content editable div. A few more steps are needed to copy its content to the clipboard.

Here is how to copy div contenteditable to the clipboard. Selecting text on the iphone and Android is not always easy. With one Copy button you can copy all the content.

<div id="editor1" contenteditable="true"></div> 

<button id="button1" onclick="CopyToClipboard()">COPY</button>

<script>

function CopyToClipboard() {

    var copyBoxElement = document.getElementById('editor1');
    copyBoxElement.contenteditable = true;
    copyBoxElement.focus();
    document.execCommand('selectAll');
    document.execCommand("copy");
    copyBoxElement.contenteditable = false;
    alert("Text has been copied")
}

</script>
  • 3
    please note execCommand is deprecated now https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand – andrea m. Jan 10 '22 at 07:59
1

Non of all these ones worked for me. But I found a duplicate of the question which the anaswer worked for me.

Here is the link

How do I copy to the clipboard in JavaScript?

iamafasha
  • 848
  • 10
  • 29