-1

I have a series of buttons, and I'd like to copy the value of the button to the clipboard after the mouse has hovered over the button for two seconds.

function getButtonValue(obj) 
{
document.getElementById(obj);
   
var dummy = document.createElement("input");
document.body.appendChild(dummy);
dummy.setAttribute('value', obj.value)
dummy.select();
document.execCommand("copy");
alert("\"" + obj.value + "\" has been copied to the clipboard.");
// document.body.removeChild(dummy);
   
} // function getButtonValue(obj)
<body>

<input type="button" id="button1" value="bite me 1" onmouseover="setTimeout(()=> getButtonValue(this), 2000);" />
<input type="text" />
<br />
<input type="button" id="button2" value="bite me 2" onmouseover="setTimeout(()=> getButtonValue(this), 2000);" />
<input type="text" />
<br />
<input type="button" id="button3" value="bite me 3" onmouseover="setTimeout(()=> getButtonValue(this), 2000);" />
<input type="text" />
<br />


</body>

I have commented out the "document.body.removeChild(dummy);" to show that the

document.body.appendChild(dummy);

dummy.setAttribute('value', obj.value);

dummy.select();

is functioning properly.

I don't get any console errors, but the button value is not getting copied to the clipboard.

The "setTimeout(()=> getButtonValue(this), 2000);" is also not working--2 seconds are passing before the "alert("\"" + obj.value + "\" has been copied to the clipboard.");" executes, but what I want is for the mouse to have to hover over the button for two seconds before the "dummy.setAttribute('value', obj.value)" is executed.

I'd like to avoid jQuery if possible and use only javascript, but will use jQuery if necessary.

I'm doing this on a Mac running 10.14.3, and using Safari 12.0.3, but get the same incorrect results on Chrome for Mac 72.0.3626.109, FireFox Quantum 65.0.1 and Opera 58.0.3135.65.

I'm also opening the page from "localhost".

Any help would be greatly appreciated.

P. James Norris
  • 158
  • 2
  • 14

1 Answers1

0

You need to affect the setTimeout into an variable to do that. And if the user leave the button, you can use clearTimeout on this variable

<input type="button" id="button1" value="bite me 1" onmouseover="foo = setTimeout(()=> getButtonValue(this), 2000);" onmouseout="clearTimeout(foo)"/>

Like that the timeout is stopped if you leave button before 2 seconds

See the live demo :

var foo, foo2, foo3;

function getButtonValue(obj) {
  const el = document.createElement('textarea');
  el.value = obj.value;
  document.body.appendChild(el);
}
  <input type="button" id="button1" value="bite me 1" onmouseover="foo = setTimeout(()=> getButtonValue(this), 2000);" onmouseout="clearTimeout(foo)" />
  <input type="text" />
  <br />
  <input type="button" id="button2" value="bite me 2" onmouseover="foo2 = setTimeout(()=> getButtonValue(this), 2000);" onmouseout="clearTimeout(foo2)" />
  <input type="text" />
  <br />
  <input type="button" id="button3" value="bite me 3" onmouseover="foo3 = setTimeout(()=> getButtonValue(this), 2000);" onmouseout="clearTimeout(foo3)" />
  <input type="text" />
  <br />

The document.execCommand() method's "cut" and "copy" commands can be used to replace the clipboard's current contents with the selected material. These commands can be used without any special permission if you are using them in a short-lived event handler for a user action (for example, a click handler).

Reference

Most browsers will only copy text to the clipboard in this way from Javascript that was directly initiated from a real user event (like a click or a key) and not from a setTimeout(). So, if your code takes the setTimeout() path, then it is likely that the copying of the text to the clipboard will not work. You can't just manufacture the keypress event - the whole point of this restriction is to require a real user event, not one manufactured by code.
In case you're interested, here's a tested function to copy text to the clipboard in this answer. It has the same restrictions as any other code - it must be initiated from Javascript that is called by a real user event and it works in modern versions of Chrome, Firefox and IE, but not in Safari.

Reference 1
Reference 2

So you can't use setTimout and document.execCommand("copy"); at the same time. Same for event mouseover, it's not an event handler for a user action

If you want to copy the text you can use the event click, like :

function getButtonValue(obj) {
  const el = document.createElement('textarea');
  el.value = obj.value;
  document.body.appendChild(el);
  el.select();
  document.execCommand("copy");
  // document.body.removeChild(el);
}
<input type="button" id="button1" value="bite me 1" onclick="getButtonValue(this)" />
<input type="text" />
<br />
<input type="button" id="button2" value="bite me 2" onclick="getButtonValue(this)" />
<input type="text" />
<br />
<input type="button" id="button3" value="bite me 3" onclick="getButtonValue(this)" />
<input type="text" />
<br />
R3tep
  • 12,512
  • 10
  • 48
  • 75