1

I am currently copying a text to clipboard using the following code:

navigator.clipboard.writeText(element.value).then(function() {
    /* clipboard successfully set */
}, function() {
    /* clipboard write failed */
    console.log('Copy to clipboard failed!');
});

I need to clear the clipboard automatically after 1 minute if the data is successfully copied to the clipboard.

I tried using setTimeout() method but write to clipboard is failing when called from setTimeout.

Also, if I am using execCommand('copy') method, I am getting the error: document.execCommand(‘cut’/‘copy’) was denied because it was not called from inside a short running user-generated event handler.

I am trying to make it work in Firefox.

The code I am trying to put inside setTimeout() is as follows:

setTimeout(function() {
    navigator.clipboard.writeText('').then(function() {
        /* Successfully cleared clipboard */
    }, function() {
        /* Failed to clear clipboard */
    }
}, 60000);
Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
Pratanu Mandal
  • 597
  • 8
  • 23
  • Are you using Firefox? Possible dupe of https://stackoverflow.com/questions/41094318/firefox-document-execcommand-cut-copy-was-denied-because-it-was-not-calle – Carcigenicate Mar 01 '19 at 23:48
  • 3
    You can't manipulate the content of the clipboard without user's direct interaction. – Teemu Mar 01 '19 at 23:52
  • Please include the `setTimeout` code that is failing. – Harry Cutts Mar 01 '19 at 23:53
  • @HarryCutts I have added the code which I am trying to execute inside setTimeout. – Pratanu Mandal Mar 02 '19 at 14:04
  • @Carcigenicate Yes, I am trying to make it work with Firefox. What I am seeking is a work-around so it works with Firefox. For my web application, I need to clear the copied text from the clipboard after 1 minute. – Pratanu Mandal Mar 02 '19 at 14:06

1 Answers1

2

Firefox requires the command to come from a user event, such as click. That's why it does not work from the handler. (You would not want some rogue javascript pasting data there, right?)

The exact wording is the command must called from

a short running user-generated event handler

Workarounds

1 Dummy input element and document.execCommand("copy")

Use a dummy input element with a single space as value, and a different API to select and copy it to the clipboard.

function clearClipboardFromSetTimeout() {
  // This should work but does not
  //if (document.selection) document.selection.empty()
  //else window.getSelection().removeAllRanges()

  // Create a dummy input to select
  var tempElement = document.createElement("input");
  tempElement.style.cssText = "width:0!important;padding:0!important;border:0!important;margin:0!important;outline:none!important;boxShadow:none!important;";
  document.body.appendChild(tempElement);
  tempElement.value = ' ' // Empty string won't work!
  tempElement.select();
  document.execCommand("copy");
  document.body.removeChild(tempElement)
}

function doIt() {
  navigator.clipboard
    .writeText("hello")
    .then(_ =>
      navigator.clipboard.readText().then(text => console.log("before", text))
    );

  setTimeout(() => {
    clearClipboardFromSetTimeout()
    navigator.clipboard.readText().then(text => console.log("after", text));
  }, 2000);
}
<div>This will Snippet will not work in Firefox, but the <em>clearClipboardFromSetTimeout</em> method will.</div>

<button onclick='doIt()'>Set Then Clear In setTimeOut</button>

2 Flash

A hacky workaround is to use Flash: https://brooknovak.wordpress.com/2009/07/28/accessing-the-system-clipboard-with-javascript/

3 Tricking The Click Handler

There are also methods of holding the click context from a user event, and then using that to trigger another click event from your handler, that in turn calls your code.

4 Browser Refresh

I am not sure if a browser refresh will clear the clipboard, but if it does, you can save your state, to local-storage perhaps, and then force a refresh.

Community
  • 1
  • 1
Steven Spungin
  • 27,002
  • 5
  • 88
  • 78