Home > Mobile >  Copy text to clipboard with JS
Copy text to clipboard with JS

Time:06-13

I am a JS beginner and I have the following problem: I want that as soon as someone clicks on the URL icon inside the accordion the respective link is copied to the clipboard. Unfortunately (always) only the first link is copied to the clipboard, even if one clicks on the other two URL icons only the first link is copied. Although in the clipboard should be link 2 (from the value field) when i click on URL icon 2 (and the same for number 3 of course). I hope I have described the problem clearly enough.

Where is the error and what do I need to change on the JS code to make it work? Thanks a lot for the help in advance!

```
<!DOCTYPE html>
<html>
<head>
  <title>My example Website</title>
<style>
body {
  font-size: 21px;
  font-family: Tahoma, Geneva, sans-serif;
  max-width: 550px;
  margin: 0 auto;
  background-color: black;
}
input {
  display: none;
}
label {
  display: block;    
  padding: 8px 22px;
  margin: 0 0 1px 0;
  cursor: pointer;
  background: #181818;
  border: 1px solid white;
  border-radius: 5px;
  color: #FFF;
  position: relative;
}
label:hover {
  background: white;
  border: 1px solid white;
  color:black;
}
label::after {
  content: ' ';
  font-size: 22px;
  font-weight: bold;
  position: absolute;
  right: 10px;
  top: 2px;
}
input:checked   label::after {
  content: '-';
  right: 14px;
  top: 3px;
}
.content {
  background: #DBEECD;
  background: -webkit-linear-gradient(bottom right, #DBEECD, #EBD1CD);
  background: -moz-linear-gradient(bottom right, #DBEECD, #EBD1CD);
  background: linear-gradient(to top left, #DBEECD, #EBD1CD);
  padding: 10px 25px 10px 25px;
  border: 1px solid #A7A7A7;
  margin: 0 0 1px 0;
  border-radius: 1px;
}
input   label   .content {
  display: none;
}
input:checked   label   .content {
  display: block;
}
.whitepaper {
cursor: pointer;
text-align: center;
background-color: white;
border: 2px solid black;
border-radius: 3px;
float: left;
margin: 5px 5px 5px 0;
height: 40px;
width: 30px;
}
.blackframe {
text-align: center;
background-color: black;
cursor: pointer;
font-family: Tahoma, Geneva, sans-serif;
font-size:12px;
font-weight:bold;
margin: 12px 0 12px 0;
color: white;
width: 30px;
}
.whitepaper:hover {
cursor: pointer;
text-align: center;
background-color: black;
border: 2px solid white;
border-radius: 3px;
float: left;
margin: 5px 5px 5px 0;
height: 40px;
width: 30px;
}
 /* Tooltip container */
.tooltip {
  position: relative;
  display: inline-block;
}

/* Tooltip text */
.tooltip .tooltiptext {
  visibility: hidden;
  width: 120px;
  background-color: #555;
  color: #fff;
  text-align: center;
  padding: 5px 0;
  border-radius: 6px;

  /* Position the tooltip text */
  position: absolute;
  z-index: 1;
  bottom: 125%;
  left: 50%;
  margin-left: -60px;

  /* Fade in tooltip */
  opacity: 0;
  transition: opacity 0.3s;
}

/* Tooltip arrow */
.tooltip .tooltiptext::after {
  content: "";
  position: absolute;
  top: 100%;
  left: 50%;
  margin-left: -5px;
  border-width: 5px;
  border-style: solid;
  border-color: #555 transparent transparent transparent;
}

/* Show the tooltip text when you mouse over the tooltip container */
.tooltip:hover .tooltiptext {
  visibility: visible;
  opacity: 1;
} 
</style>
</head>
<body>

<input type="checkbox" id="title1" name="contentbox" />
<label for="title1">Content 1</label>

<div >

<div ><div  onclick="myFunction()"><div ><span >Copy link 1 to clipboard</span>URL</div></div><input type="text" value="https://mywebsite.com/#title1" id="myInput"></div>

</div>

<input type="checkbox" id="title2" name="contentbox" />
<label for="title2">Content 2</label>

<div >

<div ><div  onclick="myFunction()"><div ><span >Copy link 2 to clipboard</span>URL</div></div><input type="text" value="https://mywebsite.com/#title2" id="myInput"></div>

</div>

<input type="checkbox" id="title3" name="contentbox" />
<label for="title3">Content 3</label>

<div >

<div ><div  onclick="myFunction()"><div ><span >Copy link 3 to clipboard</span>URL</div></div><input type="text" value="https://mywebsite.com/#title3" id="myInput"></div>

</div>

<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: "   copyText.value);
} 
</script>

</body>
</html>
```

CodePudding user response:

Replace function myFunction like this:

function myFunction(event) {
    var target = event.target;
    var copyText = target.nextElementSibling;

    navigator.clipboard.writeText(copyText.value);

    alert("Copied: "   copyText.value);
}

then update all onclick attributes like this

onclick="myFunction(event)"

CodePudding user response:

I found a few issues with your code

  1. You didn't change the id number on the inputs so they all would alert to the same URL which made it difficult to tell which is being clicked on.
  2. You are doing a query selection on an id that appears multiple times. This means it is not being fired on the clicked element.

My approach includes taking advantage of the clicked element by passing it in your click handler.

    <div >
        <div  onclick="myFunction(event)">
            <div ><span >Copy link 3 to clipboard</span>URL</div>
        </div><input type="text" value="https://mywebsite.com/#title3" id="myInput">
    </div>

This lets me pass that event to the function call which will give us access to the current target node.

function myFunction(event) {
  /* Get the text field */
    var copyText = event.target.parentNode.nextSibling.nextSibling.value

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

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

In the above case, I had to do some weird traversing because your input is outside the scope of the clicked element. I removed the code related to mobile stuff because that wasn't relevant to this issue (feel free to put that back in).

here's the codepen with my example.

  • Related