How do I copy to the clipboard in JavaScript?

Viewed 2652982
71 Answers

Reading and modifying the clipboard from a webpage raises security and privacy concerns. However, in Internet Explorer, it is possible to do it. I found this example snippet:

    <script type="text/javascript">
        function select_all(obj) {
            var text_val=eval(obj);
            text_val.focus();
            text_val.select();
            r = text_val.createTextRange();
            if (!r.execCommand) return; // feature detection
            r.execCommand('copy');
        }
    </script>
    <input value="http://www.sajithmr.com"
     onclick="select_all(this)" name="url" type="text" />

In 2018, here's how you can go about it:

async copySomething(text?) {
  try {
    const toCopy = text || location.href;
    await navigator.clipboard.writeText(toCopy);
    console.log('Text or Page URL copied');
  }
  catch (err) {
    console.error('Failed to copy: ', err);
  }
}

It is used in my Angular 6+ code like so:

<button mat-menu-item (click)="copySomething()">
    <span>Copy link</span>
</button>

If I pass in a string, it copies it. If nothing, it copies the page's URL.

More gymnastics to the clipboard stuff can be done too. See more information here:

Unblocking Clipboard Access

I use this very successfully (without jQuery or any other framework).

function copyToClp(txt){
    var m = document;
    txt = m.createTextNode(txt);
    var w = window;
    var b = m.body;
    b.appendChild(txt);
    if (b.createTextRange) {
        var d = b.createTextRange();
        d.moveToElementText(txt);
        d.select();
        m.execCommand('copy');
    } 
    else {
        var d = m.createRange();
        var g = w.getSelection;
        d.selectNodeContents(txt);
        g().removeAllRanges();
        g().addRange(d);
        m.execCommand('copy');
        g().removeAllRanges();
    }
    txt.remove();
}

Warning

Tabs are converted to spaces (at least in Chrome).

ZeroClipboard is the best cross-browser solution I've found:

<div id="copy" data-clipboard-text="Copy Me!">Click to copy</div>
<script src="ZeroClipboard.js"></script>
<script>
  var clip = new ZeroClipboard( document.getElementById('copy') );
</script>

If you need non-Flash support for iOS you just add a fall-back:

clip.on( 'noflash', function ( client, args ) {
    $("#copy").click(function(){
        var txt = $(this).attr('data-clipboard-text');
        prompt ("Copy link, then click OK.", txt);
    });
});

http://zeroclipboard.org/

https://github.com/zeroclipboard/ZeroClipboard

    $("td").click(function (e) {
        var clickedCell = $(e.target).closest("td");
        navigator.clipboard.writeText(clickedCell.text());
        alert(clickedCell.text());
    });
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr>
<td>First<td>
</tr>
<tr>
<td>Second<td>
</tr>
<tr>
<td>Third<td>
</tr>
<tr>
<td>Fourth<td>
</tr>
</table>

I've read all the answers, as of June 1st, 2020, I've beeen struggling to solve this when I finally found documentation:

$("td").click(function (e) {
    var clickedCell = $(e.target).closest("td");
    navigator.clipboard.writeText(clickedCell.text());
});

It will write the clicked cell text to the browser clipboard.

You can change the selectors "td" for anything you want, you can add console.log for debugging and/or alert functions.

Here is documentation: https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/writeText

Best and Easy way in JavaScript/TypeScript use this command

navigator.clipboard.writeText(textExample);

just pass your value what you want to copy to clipboard in textExample

The other methods will copy plain text to the clipboard. To copy HTML (i.e., you can paste results into a WYSIWYG editor), you can do the following in Internet Explorer only. This is is fundamentally different from the other methods, as the browser actually visibly selects the content.

// Create an editable DIV and append the HTML content you want copied
var editableDiv = document.createElement("div");
with (editableDiv) {
    contentEditable = true;
}
editableDiv.appendChild(someContentElement);

// Select the editable content and copy it to the clipboard
var r = document.body.createTextRange();
r.moveToElementText(editableDiv);
r.select();
r.execCommand("Copy");

// Deselect, so the browser doesn't leave the element visibly selected
r.moveToElementText(someHiddenDiv);
r.select();

This code tested @ 2021 May . Work on Chrome , IE , Edge. 'message' parameter on below is the string value you want to copy.

<script type="text/javascript">
    function copyToClipboard(message) {
        var textArea = document.createElement("textarea");
        textArea.value = message;
        textArea.style.opacity = "0"; 
        document.body.appendChild(textArea);
        textArea.focus();
        textArea.select();


        try {
            var successful = document.execCommand('copy');
            var msg = successful ? 'successful' : 'unsuccessful';
            alert('Copying text command was ' + msg);
        } catch (err) {
            alert('Unable to copy value , error : ' + err.message);
        }

        document.body.removeChild(textArea);
    }

</script>

As of Flash 10, you can only copy to clipboard if the action originates from user interaction with a Flash object. (Read the related section from Adobe's Flash 10 announcement.)

The solution is to overlay a Flash object above the Copy button, or whatever element initiates the copy. ZeroClipboard is currently the best library with this implementation. Experienced Flash developers may just want to make their own library.

Stackoverflow's Solution

I just wanted to point out that Stackoverflow actually does this. Under each answer there's a "Share" link - when you click that, it opens a popup with the share link highlighted inside an input, along with a "Copy link" link:

enter image description here

If you go to Chrome DevTools and go to the Event Listeners for that link, you can hunt down the function they use. It's called tryCopy():

enter image description here

And this is exactly consistent with Dean Taylors answer here (which was recently updated) - specifically read the section entitled "Async + Fallback". The TL;DR is: try using the navigator.clipboard api - if that's not supported by the browser, fall back to document.execCommand().

Copy text from HTML input to the clipboard:

 function myFunction() {
   /* Get the text field */
   var copyText = document.getElementById("myInput");

   /* Select the text field */
   copyText.select();

   /* Copy the text inside the text field */
   document.execCommand("Copy");

   /* Alert the copied text */
   alert("Copied the text: " + copyText.value);
 }
 <!-- The text field -->
 <input type="text" value="Hello Friend" id="myInput">

 <!-- The button used to copy the text -->
<button onclick="myFunction()">Copy text</button>

Note: The document.execCommand() method is not supported in Internet Explorer 9 and earlier.

Source: W3Schools - Copy Text to Clipboard

Best Way to Copy the text inside the text field. Use navigator.clipboard.writeText.

<input type="text" value="Hello World" id="myId">
<button onclick="myFunction()" >Copy text</button>

<script>
function myFunction() {
  var copyText = document.getElementById("myId");
  copyText.select();
  copyText.setSelectionRange(0, 99999);
  navigator.clipboard.writeText(copyText.value);
}

</script>

This works straight away, using the newest Clipboard API, and a user interaction:

copy.addEventListener("pointerdown", () => navigator.clipboard.writeText("Hello World!"))
<button id="copy">Copy Hello World!</button>

In browsers other than Internet Explorer you need to use a small Flash object to manipulate the clipboard, e.g.

I had the same problem building a custom grid edit from (something like Excel) and compatibility with Excel. I had to support selecting multiple cells, copying and pasting.

Solution: create a textarea where you will be inserting data for the user to copy (for me when the user is selecting cells), set focus on it (for example, when user press Ctrl) and select the whole text.

So, when the user hit Ctrl + C he/she gets copied cells he/she selected. After testing just resizing the textarea to one pixel (I didn't test if it will be working on display:none). It works nicely on all browsers, and it is transparent to the user.

Pasting - you could do same like this (differs on your target) - keep focus on textarea and catch paste events using onpaste (in my project I use textareas in cells to edit).

I can't paste an example (commercial project), but you get the idea.

function copytoclipboard(element) {

    var $temp = $("<input>");
    $("body").append($temp);
    $temp.val('0' + element).select();
    document.execCommand("copy");
    $temp.remove();
}

Try to use this function


const copyToClipboard = (
  value,
  successfully = () => null,
  failure = () => null
) => {
  const clipboard = navigator.clipboard;
  if (clipboard !== undefined && clipboard !== "undefined") {
    navigator.clipboard.writeText(value).then(successfully, failure);
  } else {
    if (document.execCommand) {
      const el = document.createElement("input");
      el.value = value;
      document.body.append(el);

      el.select();
      el.setSelectionRange(0, value.length);

      if (document.execCommand("copy")) {
        successfully();
      }

      el.remove();
    } else {
      failure();
    }
  }
};

To copy a selected text ('Text To Copy') to your clipboard, create a Bookmarklet (browser bookmark that executes JavaScript) and execute it (click on it). It will create a temporary textarea.

Code from GitHub:

https://gist.github.com/stefanmaric/2abf96c740191cda3bc7a8b0fc905a7d

(function (text) {
  var node = document.createElement('textarea');
  var selection = document.getSelection();

  node.textContent = text;
  document.body.appendChild(node);

  selection.removeAllRanges();
  node.select();
  document.execCommand('copy');

  selection.removeAllRanges();
  document.body.removeChild(node);
})('Text To Copy');

This was the only thing I ever got working, after looking up various ways all around the Internet. This is a messy topic. There are lots of solutions posted around the world and most of them do not work. This worked for me:

NOTE: This code will only work when executed as direct synchronous code to something like an 'onClick' method. If you call in an asynchronous response to Ajax or in any other asynchronous way it will not work.

copyToClipboard(text) {
    var copyText = document.createElement("input");
    copyText.type = "text";
    document.body.appendChild(copyText);
    copyText.style = "display: inline; width: 1px;";
    copyText.value = text;
    copyText.focus();
    document.execCommand("SelectAll");
    document.execCommand("Copy");
    copyText.remove();
}

I do realize this code will show a 1-pixel wide component visibly on the screen for a millisecond, but decided not to worry about that, which is something that others can address if a real problem.

It looks like you took the code from Greasemonkey\JavaScript Copy to Clipboard button or the original source of this snippet...

This code was for Greasemonkey, hence the unsafeWindow. And I guess the syntax error in Internet Explorer comes from the const keyword which is specific to Firefox (replace it with var).

This solution was found here. The document.execCommand("copy"); is not supported on Internet Explorer 8 and earlier.

const copyBtn =  document.getElementById("copyBtn");
const input = document.getElementById("input");

function copyText() {
  const value = input.value;
  
  input.select(); // selects the input variable as the text to be copied
  input.setSelectionRange(0, 99999); // this is used to set the selection range for mobile devices
  
  document.execCommand("copy"); // copies the selected text
  
  alert("Copied the text " + value); // displays the copied text in a prompt
}

copyBtn.onmousedown = function () {
  copyText();
}
<input type="text" id="input" placeholder="Type text to copy... "/>
<button id="copyBtn">
  Copy
</button>

Simple, ready-to-use and not obsolete solution:

function copyToClipboard(elementIdToCopy, elementIdToNotifyOutcome) {
    const contentToCopy = document.getElementById(elementIdToCopy).innerHTML;
    const elementToNotifyOutcome = document.getElementById(elementIdToNotifyOutcome);

    navigator.clipboard.writeText(contentToCopy).then(function() {
        elementToNotifyOutcome.classList.add('success');
        elementToNotifyOutcome.innerHTML = 'Copied!';
    }, function() {
        elementToNotifyOutcome.classList.add('failure');
        elementToNotifyOutcome.innerHTML = 'Sorry, did not work.';
    });
}

This was the only thing that worked for me:

let textarea = document.createElement('textarea');
textarea.setAttribute('type', 'hidden');
textarea.textContent = 'the string you want to copy';
document.body.appendChild(textarea);
textarea.select();
document.execCommand('copy');

Using the JavaScript feature using try/catch you can even have better error handling in doing so like this:

copyToClipboard() {
    let el = document.getElementById('Test').innerText
    el.focus(); // el.select();
    try {
        var successful = document.execCommand('copy');
        if (successful) {
            console.log('Copied Successfully! Do whatever you want next');
        }
        else {
            throw ('Unable to copy');
        }
    }
    catch (err) {
        console.warn('Oops, Something went wrong ', err);
    }
}

Using document.execCommand will do the job for you...

Using that, you can also do cut, copy and paste...

This is one simple clipboard copy functionality which copies everything from input text...

function copyInputText() {
  var copyText = document.querySelector("#input");
  copyText.select();
  document.execCommand("copy");
}

document.querySelector("#copy").addEventListener("click", copyInputText);
<input id="input" type="text" />
<button id="copy">Copy</button>

For more information, see Interact with the clipboard (add-on).

This is a standalone class and ensures no flashing could occur from the temporary textarea by placing it off-screen.

This works in Safari (desktop), Firefox, and Chrome.

// ================================================================================
// ClipboardClass
// ================================================================================
var ClipboardClass = (function() {

    function copyText(text) {
        // Create a temporary element off-screen to hold text.
        var tempElem = $('<textarea style="position: absolute; top: -8888px; left: -8888px">');
        $("body").append(tempElem);

        tempElem.val(text).select();
        document.execCommand("copy");
        tempElem.remove();
    }


    // ============================================================================
    // Class API
    // ============================================================================
    return {
        copyText: copyText
    };

})();

The below function can be used to copy into the clipboard:

copyToclipboard = (event, text) => {
    var container = event.currentTarget;
    let tempInnerHtml = container.innerHTML;
    container.innerHTML = text;
    window.getSelection().removeAllRanges();
    let range = document.createRange();
    range.selectNode(container);
    window.getSelection().addRange(range);
    document.execCommand('copy');
    window.getSelection().removeAllRanges();
    container.innerHTML = tempInnerHtml;
}

Adding on to Dean Taylor's answer, here is a short answer and a long one, so you can just copy the function that suits your needs:

Short Answer:

Just use navigator.clipboard.writeText(str)

See the clipboard API on caniuse.com

Long Answer:

    // Copies a string to clipboard
    // Uses navigator API if available, else uses execCommand (deprecated)
    // Returns a boolean if copy was successful
    // See: https://stackoverflow.com/q/400212/4907950
        async function copyText(str) {
        console.log('Copying', str);
        if (!navigator.clipboard) {
            // fallback
            let input = document.createElement('textarea');
            input.innerHTML = str;
            document.body.appendChild(input);
            input.focus();
            input.select();
            let result;

            try {
                result = document.execCommand('copy');
                console.log(
                    'Fallback: Copying text command was ' + (result ? 'successful' : 'unsuccessful')
                );
            } catch (err) {
                console.error('Fallback: Could not copy text: ', err);
            }
            document.body.removeChild(input);
            return result;
        }
        const result = navigator.clipboard.writeText(str).then(
            function () {
                console.log('Async: Copying to clipboard was successful');
                return true;
            },
            function (err) {
                console.error('Async: Could not copy text: ', err);
                return false;
            }
        );
        return result;

Here is an easy example ;)

<!DOCTYPE html>
<html>
    <body>
        <input type="text"
               value="Hello, World!"
               id="myInput">
        <button onclick="myFunction()">Copy text</button>

        <p>The document.execCommand() method is not supported
           in Internet&nbsp;Explorer&nbsp;8 and earlier.</p>

        <script>
            function myFunction() {
                var copyText = document.getElementById("myInput");
                copyText.select();
                document.execCommand("copy");
                alert("Copied the text: " + copyText.value);
            }
        </script>
    </body>
</html>
document.querySelector('#some_your_textfield_id').select();
document.execCommand('copy');

The first line is to select the text that you want to copy.

The second line is to copy the selected text.

this is the easiest way i found

<!DOCTYPE html>
<html>
<body>

 <p>Click on the button to copy the text from the text field. Try to paste 
 the text (e.g. ctrl+v) afterwards in a different window, to see the effect. 
 </p>

  <input type="text" value="Hello World" id="myInput">
  <button onclick="myFunction()">Copy text</button>

  <script>
 function myFunction() {
   /* Get the text field */
   var copyText = document.getElementById("myInput");

  /* Select the text field */
   copyText.select();
    copyText.setSelectionRange(0, 99999); /* For mobile devices */

   /* Copy the text inside the text field */
   navigator.clipboard.writeText(copyText.value);

   /* Alert the copied text */
    alert("Copied the text: " + copyText.value);
    }

   </script>

    </body>
    </html>

This is my take on the answer based on everyone's answers. Do note that this answer considers a few things:

  1. Made sure that navigator.clipboard.writeText() is the primary way of copying
  2. Made sure that writeText() promise is properly resolved using modern JS -- as per 2022.

   async function copyText(e) {
        const elem = e.currentTarget;
        const text = elem.textContent;
        try {
          await navigator.clipboard.writeText(text);
          elem.textContent = "Copied to Clipboard!";
        } catch (err) {
          //use document.execCommand('copy') as fallback
          const textArea = document.createElement("textarea");
          textArea.value = text;
          document.body.appendChild(textArea);
          textArea.focus();
          textArea.select();
          document.execCommand("copy");
          elem.textContent = "Copied to Clipboard!";
          document.body.removeChild(textArea);
        } finally {
          setTimeout(() => {
            elem.textContent = text;
          }, 2000);
        }
      }
      document.querySelector(".target-elem-whatever").addEventListener("click", copyText);
<button class="target-elem-whatever">This text should be inside your clipboard.</button>

Here is my solution:

var codeElement =
    document.getElementsByClassName("testelm") &&
        document.getElementsByClassName("testelm").length ?
    document.getElementsByClassName("testelm")[0] :
    "";
if (codeElement != "") {
    var e = document.createRange();
    e.selectNodeContents(codeElement);
    var selection = window.getSelection();
    selection.removeAllRanges();
    selection.addRange(e);
    document.execCommand("Copy");
    selection.removeAllRanges();
}

This can be done just by using a combination of getElementbyId, Select(), blur() and the copy command.

Note

The select() method selects all the text in a <textarea> element or an <input> element with a text field. This might not work on a button.

Usage

let copyText = document.getElementById('input-field');
copyText.select()
document.execCommand("copy");
copyReferal.blur()
document.getElementbyId('help-text').textContent = 'Copied'

The blur() method will remove the ugly highlighted portion instead of that you can show at beautiful message that your content was copied successfully.

I have tried many solutions. If it works in modern browsers, it won't in Internet Explorer. If it works in Internet Explorer, it won't on iOS. I finally groomed them all and arrived at the below fix that works in all the browsers, iOS, webview, and Android.

Note: I also covered the scenario where the user denies permission to the clipboard. Additionally, the message "link copied" will be displayed even if the user copies manually.

<div class="form-group col-md-12">
    <div class="input-group col-md-9">
        <input name="copyurl"
               type="text"
               class="form-control br-0 no-focus"
               id="invite-url"
               placeholder="http://www.invitelink.com/example"
               readonly>
        <span class="input-group-addon" id="copy-link" title="Click here to copy the invite link">
            <i class="fa fa-clone txt-18 text-success" aria-hidden="true"></i>
        </span>
    </div>
    <span class="text-success copy-success hidden">Link copied.</span>
</div>

Script:

var addEvent =  window.attachEvent || window.addEventListener;
var event = 'copy';
var $inviteUrl = $('#invite-url');

$('#copy-link').on('click', function(e) {
    if ($inviteUrl.val()) {
        if (navigator.userAgent.match(/ipad|ipod|iphone/i)) {
            var el = $inviteUrl.get(0);
            var editable = el.contentEditable;
            var readOnly = el.readOnly;
            el.contentEditable = true;
            el.readOnly = false;
            var range = document.createRange();
            range.selectNodeContents(el);
            var sel = window.getSelection();
            sel.removeAllRanges();
            sel.addRange(range);
            el.setSelectionRange(0, 999999);
            el.contentEditable = editable;
            el.readOnly = readOnly;
            document.execCommand('copy');
            $inviteUrl.blur();
        }
        else {
            $inviteUrl.select();
            document.execCommand("copy");
        }
    }
});

addEvent(event, function(event) {
    if ($inviteUrl.val() && event.target.id == 'invite-url') {
        var $copyLink = $('#copy-link i');
        $copyLink.removeClass('fa-clone');
        $copyLink.addClass('fa-check');
        $('.copy-success').removeClass('hidden');
        setTimeout(function() {
            $copyLink.removeClass('fa-check');
            $copyLink.addClass('fa-clone');
            $('.copy-success').addClass('hidden');
        }, 2000);
    }
});

To me less is more

const text = "Copy me please!";
navigator.clipboard.writeText(text);

All good.

This could be the solution to your problem

function CopyToNotepad(id){
    var r = document.createRange();
    r.selectNode(document.getElementById(id));
    window.getSelection().removeAllRanges();
    window.getSelection().addRange(r);
    document.execCommand('copy');
    window.getSelection().removeAllRanges();
}

Note: id should be the parent element id to which you want to copy the content. Eg: suppose you want to copy every content inside the list, then id should be used as follows:

<ul id="dummy_id">
<li>copy content 1 </li>
<li>copy content 2 </li>
<li>copy content 3 </li>
<li>copy content 4 </li>
<li>copy content 5 </li>
</ul>

then function call should be like this

CopyToNotepad(dummy_id)

Thanks. Sure this could solve your problem!

Related