How to target only the clicked class with javascript

179 Views Asked by At

I'm trying to create an experience when someone clicks on a text it's copied and then it's replaced with a random phrase.

When I use document.querySelector(".clickMe") it will only affect the first instance of .clickMe. I would like to change the text of any of the p tags with .clickMe that was clicked on, not any other. How do I do this?

      function copy(that){
            var inp =document.createElement('input');
            document.body.appendChild(inp)
            inp.value =that.textContent
            inp.select();
            document.execCommand('copy',false);
            inp.remove();
        }

var randomStrings = [
            "Roger Roger!",
            "Copied Copycat!",
            "Got it!", 
            "It's on the clipboard!",
            "Instantly memorized!",
            "Go paste it somewhere!",
            "Photocopied!",
            "Score!",
            "Your receipt!",
            "Literally copied!",
            "Carbon copied!",
            "Great artists steal!",
            "Precisely rendered!",
            "Virtually cloned!",
            "You got the knock off!",
            "Copy parady!",
            "Text impersonator!",
            "Hurry go paste it!",
            "So unoriginal!",
            "You got it!"
        ];

        document.querySelector(".clickMe").addEventListener("click", function() {
              randomIndex = Math.ceil((Math.random()*randomStrings.length-1));
              newText = randomStrings[randomIndex];
              this.innerHTML = newText;
        });
p {
  font-family: Helvetica;
  font-size: 20px;
  font-weight: 600;
  color: OliveDrab;
  transition: all ease 0.3s;
}

p:hover {
  cursor: pointer;
  color: BurlyWood;
}
<p class="clickMe" onclick="copy(this)">Text One</p>

<p class="clickMe" onclick="copy(this)">Text Two</p>

<p class="clickMe" onclick="copy(this)">Text Three</p>

<p class="clickMe" onclick="copy(this)">Text Four</p>

<p class="clickMe" onclick="copy(this)">Text Five</p>

1

There are 1 best solutions below

1
On

Either iterate over all such elements with querySelectorAll and add a listener to each element, or use event delegation. Don't mix inline handlers and addEventListener - preferably, don't use inline handlers at all:

for (const p of document.querySelectorAll('.clickMe')) {
  p.addEventListener('click', () => {
    const randomIndex = Math.ceil((Math.random() * randomStrings.length - 1));
    const newText = randomStrings[randomIndex];
    p.innerHTML = newText;
    copy(p);
  });
}

function copy(that) {
  var inp = document.createElement('input');
  document.body.appendChild(inp)
  inp.value = that.textContent
  inp.select();
  document.execCommand('copy', false);
  inp.remove();
}

var randomStrings = [
  "Roger Roger!",
  "Copied Copycat!",
  "Got it!",
  "It's on the clipboard!",
  "Instantly memorized!",
  "Go paste it somewhere!",
  "Photocopied!",
  "Score!",
  "Your receipt!",
  "Literally copied!",
  "Carbon copied!",
  "Great artists steal!",
  "Precisely rendered!",
  "Virtually cloned!",
  "You got the knock off!",
  "Copy parady!",
  "Text impersonator!",
  "Hurry go paste it!",
  "So unoriginal!",
  "You got it!"
];
<p class="clickMe">Text One</p>

<p class="clickMe">Text Two</p>

<p class="clickMe">Text Three</p>

<p class="clickMe">Text Four</p>

<p class="clickMe">Text Five</p>