Search code examples
javascripttooltip

How to copy to clipboard and change tooltips at the same time with JS


I want to click to copy numbers to the clipboard and change the tooltip text from "Copy to clipboard" to "Copied: [number]" when clicked.

With many numbers, I don't want to use IDs to reduce my code.

I have managed to copy numbers to the clipboard but I am struggling with tooltips.

Any help or hint would be appreciated.

const tds = document.querySelectorAll(".number");

tds.forEach(td => {
  td.onclick = function () {
    document.execCommand("copy");
  }

  td.addEventListener("copy", function (event) {
    event.preventDefault();
    if (event.clipboardData) {
      event.clipboardData.setData("text/plain", td.textContent);
      console.log(event.clipboardData.getData("text"));
      //the below 2 lines doesn't work
      var tooltip = document.getElementsByClassName("tooltiptext");
      tooltip.innerHTML = "copied" + event.clipboardData.getData("text");
    }
  });
})

function outFunc() {
  var tooltip = document.getElementsByClassName("tooltiptext");
  tooltip.innerHTML = "Copy to clipboard";
} 
.tooltip {
  position        : relative;
  display         : inline-block;
  }
.tooltip .tooltiptext {
  visibility      : hidden;
  width           : 140px;
  background-color: #555;
  color           : #fff;
  text-align      : center;
  border-radius   : 6px;
  padding         : 5px;
  position        : absolute;
  z-index         : 1;
  bottom          : 150%;
  left            : 50%;
  margin-left     : -75px;
  opacity         : 0;
  transition      : opacity 0.3s;
  }
.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;
  }
.tooltip:hover .tooltiptext {
  visibility      : visible;
  opacity         : 1;
  }
<div class="tooltip">
  <span class="tooltiptext">Copy to clipboard</span>
  <a style="font-size: 2em;" onmouseout="outFunc()" class="number">1</a>
</div>
<div class="tooltip">
  <span class="tooltiptext">Copy to clipboard</span>
  <a style="font-size: 2em;" onmouseout="outFunc()" class="number">2</a>
</div>
<div class="tooltip">
  <span class="tooltiptext">Copy to clipboard</span>
  <a style="font-size: 2em;" onmouseout="outFunc()" class="number">3</a>
</div>
<div class="tooltip">
  <span class="tooltiptext">Copy to clipboard</span>
  <a style="font-size: 2em;" onmouseout="outFunc()" class="number">4</a>
</div>


Solution

  • This biggest problem is you doesn't specify the [] for document.getElementsByClassName. .

    There is one problem that you have noticed: It won't display the copy information correctly if you copy the two number or more at the same time because you assign the copy function to each individual <span>

    Updated: I change the document.getElementsByClassName to document.querySelectorAll in order to use forEach, but if you don't want to, just use a for loop.

    Also, your copy message currently will not working because you set bottom: 150% and `opacity:0

    You should use mouseenter.

    const tds = document.querySelectorAll(".number");
    
    
    document.querySelectorAll(".tooltiptext").forEach(link =>{
    link.addEventListener('mouseenter',function(){
    link.textContent = 'Copy and paste'
    })
    })
    tds.forEach(td => {
      td.onclick = function () {
        document.execCommand("copy");
      }
    
      td.addEventListener("copy", function (event) {
        event.preventDefault();
        if (event.clipboardData) {
          event.clipboardData.setData("text/plain", td.textContent);
          console.log(event.clipboardData.getData("text"));
          //the below 2 lines doesn't work
          var tooltip = document.querySelectorAll(".tooltiptext");
          tooltip.forEach(item =>{
            item.innerHTML = "copied" + event.clipboardData.getData("text");
          })
        }
      });
    })
    
    function outFunc() {
      var tooltip = document.querySelectorAll(".tooltiptext");
          tooltip.forEach(item =>{
            item.innerHTML = "Copy to clipboard";
          })
    }
    .tooltip {
      position        : relative;
      display         : inline-block;
      }
    .tooltip .tooltiptext {
      
      width           : 140px;
      background-color: #555;
      color           : #fff;
      text-align      : center;
      border-radius   : 6px;
      padding         : 5px;
      position        : absolute;
      z-index         : 1;
      left            : 50%;
      margin-left     : -75px;
      transition      : opacity 0.3s;
      }
    .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;
      }
    .tooltip:hover .tooltiptext {
      visibility      : visible;
      opacity         : 1;
      }
    <div class="tooltip">
      <span class="tooltiptext">Copy to clipboard</span>
      <a style="font-size: 2em;" onmouseout="outFunc()" class="number">1</a>
    </div>
    <div class="tooltip">
      <span class="tooltiptext">Copy to clipboard</span>
      <a style="font-size: 2em;" onmouseout="outFunc()" class="number">2</a>
    </div>
    <div class="tooltip">
      <span class="tooltiptext">Copy to clipboard</span>
      <a style="font-size: 2em;" onmouseout="outFunc()" class="number">3</a>
    </div>
    <div class="tooltip">
      <span class="tooltiptext">Copy to clipboard</span>
      <a style="font-size: 2em;" onmouseout="outFunc()" class="number">4</a>
    </div>