Jump to content
Tuts 4 You

JavaScript - How to create a working function to copy data to Clipboard?


LCF-AT

Recommended Posts

Posted

Hi guys,

at the moment I try to play around with JavaScript again to make any script (very basic) and now I have that problem to copy data / text into system Clipboard. Can anyone show a basic working example to create a function that copies the send API parameter into Clipboard if I need it? Example....

var HOLD1 = "Some_Text_to_COPY";
var input=document.createElement("input");
  input.type="button";
  input.value="Copy Title"
  input.onclick = CopyClipBoard(HOLD1);
  document.body.appendChild(input);

function CopyClipBoard(SOMETHING) {
  SOMETHING.select();
  SOMETHING.setSelectionRange(0, 99999); // For mobile devices
  navigator.clipboard.writeText(SOMETHING.value);
}

...I just create a button on html and if I click on the button then it should call my CopyClipBoard function with the HOLD1 variable where I have put a string text into. First problem I have is that I get error messages about select / setSelectionRange  is not a function. No idea why I get this error if I test that on https://developer.mozilla.org/de/play. Also if I use the last command alone "navigator.clipboard.writeText(SOMETHING.value);" I don't get a error message but it will also not copy the text into Clipboard. Why? So my goal is it just to make a simple function I can call multiple times from anywhere with the content I want to copy into Clipboard. Can anyone tell me how to adjust the function to make it work? Thanks.

Posted
<!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>

 

  • Confused 1
Posted

Hey @NOP,

thanks for trying to help but this is not what I was looking for. I don't use script tags inside the html I do run the script from outside only. I also want to create a global CopyClipBoard function without to enter static variables inside of the function you know. Look below...

invoke CopyClipBoard, addr HOLD1 // any string content
invoke CopyClipBoard, addr HOLD2 // any string content
invoke CopyClipBoard, addr HOLD3 // any string content

My Function:
CopyClipBoard, Parameter
-----------------------------------------
copy content in Parameter to Clipboard
ret

...I just want to call the CopyClipBoard from anywhere I want with any variable filled XY parameter to copy the content into clipboard in JavaScript code only etc. How to do that make it work?

greetz

Posted (edited)

Maybe this will help you

// Global function
async function CopyClipBoard(text) {
  try {
    await navigator.clipboard.writeText(text);
    console.log("Text copied to clipboard:", text);
  } catch (err) {
    console.error("Failed to copy:", err);
  }
}

// button
document.getElementById("copyBtn").addEventListener("click", () => {
  CopyClipBoard("This is the text copied when clicking the button!");
});

//////////////////////////////////////////////////////////////////////////////////


async function copyContent() {
  try {
    await navigator.clipboard.writeText("This is the text to be copied");
    console.log("Content copied to clipboard");
  } catch (err) {
    console.error("Failed to copy: ", err);
  }
}

// Copy when the user presses any key
document.addEventListener("keydown", copyContent);

// Copy when the user moves the mouse
document.addEventListener("mousemove", copyContent, { once: true });


 

https://medium.com/front-end-weekly/how-to-listen-to-the-contents-of-the-clipboard-in-the-browser-aadb0accaa19
https://www.freecodecamp.org/news/copy-text-to-clipboard-javascript/
https://dev.to/david_bilsonn/how-to-save-a-string-to-clipboard-in-javascript-13ie

Edited by Kanes
  • Like 1
Posted

Hi @Kanes,

your example does not work for me. I get error ""Failed to copy:" NotAllowedError: Clipboard write was blocked due to lack of user activation." on

https://developer.mozilla.org/en-US/play

and in browser using Violentmonkey / script to test it does not work too IF I press the button to copy. It only does copy if I load the website but it should just copy to Clipboard when I press on the button to copy it. So it does not work correctly as I want. Only thing to make it work is using the same variable inside of the function like this...

var something = "STRING";
var others = "STRING_2";

var input=document.createElement("input");
input.type="button";
input.value="Copy Text";
input.onclick = copyToClipboard;  // <--- without variable
document.body.appendChild(input);

var input=document.createElement("input");
input.type="button";
input.value="Copy Text 2";
input.onclick = copyToClipboard;  // <--- without variable
document.body.appendChild(input);                                          
                                          
                                          
function copyToClipboard() {
    navigator.clipboard.writeText(something);
}
                                          
function copyToClipboard() {
    navigator.clipboard.writeText(others);
}

...in this case I made 2 buttons and did link them with onClick to call my function without any parameter for the variable and this works BUT I have to use static variables inside of my function and I have to create them again and again what is bad and illogically. I just want to use ONE function to copy the content / text in the variable to Clipboard and that's it. So why is it not working? I spend already hours just to find that out but without success. :) Any other ideas?

greetz

Posted (edited)

@LCF-AT

In that case it's because it's running inside an iframe with restrictions. It should work fine in a regular HTML page or in a browser extension with special permissions, but following your example you can do this in the playground

function CopyClipBoard(text) {
    let tempInput = document.body.appendChild(document.createElement("input"));
    tempInput.value = text;
    tempInput.select();
    document.execCommand("copy");
    tempInput.remove();
}

function createCopyButton(text) {
    let button = document.body.appendChild(document.createElement("button"));
    button.textContent = `Copy: ${text}`;
    button.onclick = () => CopyClipBoard(text);
}

// String example
createCopyButton("String example");

 

Edited by Kanes
  • Like 2
Posted

@Kanes

Thanks for the example. Seems to work. I see that I just had do to ONE change in my code at the "input.onclick =*" command...

var something = "STRING";
var others = "STRING_2";

input.onclick = copyToClipboard;  // <--- without variable
to
input.onclick = () => copyToClipboard(something);
input.onclick = () => copyToClipboard(others);

  
function copyToClipboard(text) {
    navigator.clipboard.writeText(text);
}

....and then its working by just changing that one command. So could you explain that command why to write it in that style and what does it mean? So before I tried this style...

input.onclick = copyToClipboard(something); 	 // <-- not working

input.onclick = () => copyToClipboard(something); // <-- working

....only different I see is that...

 () => 

...command. Sign for function () and => so what is it meaning? Just found something about arrow functions but still don't know what it really means now.

greetz

  • Like 1
Posted

@LCF-AT oh you are right

>>> input.onclick = copyToClipboard(something);
In this case copyToClipboard(something) is executed immediately, and the returned value (undefined) is what gets assigned to onclick

>>> input.onclick = () => copyToClipboard(something);
Here, instead, you're assigning an anonymous function, a function that doesn't run right away
You're assigning the entire function to the onclick event. So, only when the user clicks, copyToClipboard(something) will be executed

https://www.javascripttutorial.net/javascript-anonymous-functions/
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions
 

  • Like 1
  • Thanks 1
Posted (edited)

OK thanks for that info @Kanes.

So I did notice another NEW problem today. Somehow the window.open("URL") function does not work always! Why this? Somehow it happens nothing when calling that function but the console log function works inside that function. Could it be that window.open get blocked without to get any error / info about it?

let url = "https://forum.tuts4you.com";

var input=document.createElement("input");
input.type="button";
input.value=url;
input.onclick = () => showAlert(url);
document.body.appendChild(input).style.cursor = "pointer";


function showAlert(text) {
    window.open(text);
    console.log(text);
}

When I try this code above on https://developer.mozilla.org/de/play then it tells me "InvalidAccessError: A parameter or an operation is not supported by the underlying object" error. In my test script it works just partial not for all websites I have test. Somehow strange. How to make it work always? The console.log(text) function inside showAlert function works always but not the window.open function. Do you know what the reason could be?

greetz

EDIT: By the way, I have test my script in Firefox and its not working / showing any buttons there etc as it does in Brave browser! Uhm! GREAT! :kick:Another problem I need to find out what the reason for this is.

Edited by LCF-AT
Added Info
  • Like 2
Posted (edited)

@LCF-AT 

If you want window.open() to work, you need to run the code in an unrestricted environment. The web is full of restrictions to prevent security vulnerabilities between the browser and the client because the browser itself acts as a sandbox. In this case, I don’t think there’s a conventional way to solve it, since a malicious JavaScript script using alert() could be used to compromise a machine and steal session cookies from the site where it's executed. For this and other reasons, browsers block pop-up by default.  also since you're running the code inside an <iframe> there's another issue you need explicit permission to allow popups in that context

To test this, you can inspect and modify the HTML on MDN Play by adding the allow-popups permission inside the <iframe>. If the browser isn’t blocking popups globally your code should work. (If not, then it's another block from the browser itself)

You just reminded me of an interesting topic related to this, which is covered on this channel. They have great content:
www  .  youtube.com/watch?v=lG7U3fuNw3A

 

 

 

ENV.png

Edited by Kanes
  • Like 2
Posted

@Kanes

Thanks for the new info's. Seems I have the same problem if I try to create a LINK instead of a button so it also not works. This is bad. I'm using Brave & Firefox and they seems to handle it differently. In case of Brave its working to show buttons and to use window.open (mostly) but in case of Firefox I don't get anything to see IF I have enabled uBlockOrigin (using in both browses with same setup). If I disable uBO then my button is showing and working but also the website ADS garbage. How to deal with that now? First, I need to have uBO enabled of course but in Firefox I don't get my button to see if so. No idea what to do now. Brave works Firefox not. By the way, on that webiste jsfiddle.net it works to use the button with a link to open it.

Another question, how to tell Javascript to execute my code AFTER the website was fully loaded and how to tell to execute my script right away? I found this to tell JS to execute after website was fully loaded..

window.addEventListener('load', (event) => {
  console.log('page is fully loaded');

	...my code...

});

...but I'm not sure even not in case of Firefox. Sometimes I get the message that some ID I was looking for was not found but its there if I check the site in inspector console. That's also strange somehow. I found another problem just trying to write some console.log string when website is fully loaded on Example.com.

console.log('TEST 123');
window.addEventListener('load', (event) => {
  console.log('page is fully loaded');

	...my code...

});

So when I test this little code then "TEST 123" gets logged but 'page is fully loaded' NOT. Why? I also have uBO disabled.

greetz

  • Like 1
Posted

OK, so I have this problem trying to find a element by ID which is there but I get this error in Firefox...

Uncaught TypeError: document.getElementById(...) is null

....if I try to execute a simple command....

let url = document.getElementById("url").querySelector("source").src;
if (url) {
  console.log(url);
}else{
  console.log("Failed to find url ID element!");
  return
}

...so it does not get the element but its there. I don't understand that. I found another strange thing. So if I use the debugger in browser to set BP on the line above then it works to read the element and source. Pretty strange! No idea what the problem is and why it works in debug mode and not in normal mode in Firefox. :( 

greetz

  • Like 1
Posted
17 hours ago, LCF-AT said:

 

If I disable uBO then my button is showing and working but also the website ADS garbage. How to deal with that now? First, I need to have uBO enabled of course but in Firefox I don't get my button to see if so. 

Your examples work fine. I guess the issue is that you have ublock set too strictly, blocking even javascript. just add an exception for the page or disable javascript blocking in the settings. Testing in a restrictive environment probably isn’t the best way to practice.
and  for "document.getElementById(...) is null", that's normal if the element isn't found. So the issue could be related to timing for example, if the element is loaded dynamically and the check happens before it has been created. You could try using 'DOMContentLoaded' instead of 'load'.

 

  • Like 2
Posted

Hi, thanks for checking. I have big differences using Brave / Chromium and Firefox with my script. I tried this now. I disabled uBO completely from both browsers and then I disabled all cookies (Firefox settings) for that specific website and in Brave too. In case of Firefox my script does not create a button but in Brave it does. Why this? If I allow cookies on that website in Firefox then it works and my script does create the button. Really strange behaving. Do you have any explanation for this?

Brave:		Block All Cookies | no uBO | My Script | = Working to create button
Firefox:	Block All Cookies | no uBO | My Script | = Failed to create button (Uncaught TypeError: document.getElementById(...) is null)

It does not get the element by ID in FF. By the way, the does not work better or at all. It does not work if I use it instead of "load".

Somehow pretty frustrating right now not getting it work for both browser yet. No idea how to deal with that. :( 

EDIT: I see problem when using...

window.addEventListener('load', (event) => {
...my code...
});

...so sometimes it works sometimes not, its like 50/50. Now I was looking for some sleep function I could place at the top in my script and found just this one...

// sleep time expects milliseconds
function sleep (time) {
  return new Promise((resolve) => setTimeout(resolve, time));
}

// Usage!
sleep(500).then(() => {
    // Do something after the sleep!
});

....and if I se this function with sleep of 1 seconds and let execute my code inside then it works! :) So the problem is that I need to wait a while longer in Firefox (not in Brave) to find that element as you did mention already. Seems I have to work with sleep functions etc.

Question: Is there also a method to sleep at any line I want (like in coding you call sleep function with time X and in this time all stops before next code get executed / no threads)? The problem is I have to put all my code inside of this sleep function but I would prefer to stop right there. Otherwise if you have any other and better ideas how to tell JS to sleep or how to continue after website and all components are fully loaded then tell me. Thanks.

greetz

  • Like 1
Posted

Use async and await.

// sleep time expects milliseconds
async function sleep (time) {
  await new Promise((resolve) => setTimeout(resolve, time));
}

window.addEventListener('load', async (event) => {
await sleep(500);
...my code...
});

 

  • Like 1

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...