0

I got multiple buttons need to use a same function where the button text will change when someone click it.

I use the event handler attributes with JavaScript code to achieve the effect. However, no matter which button I've clicked, always only the first button executing the function...

Please run the code snippet below then you will understand🙏

function myFunction() {
  document.querySelector(".demo span").innerHTML = "Copied";
  setTimeout(function(){ document.querySelector(".demo span").innerHTML = "Find Out More"; }, 1000);
}
.Big {
  width: 257px;
  padding: 33px 0 30px 0;
  font-size: 21px;
}

button {
  font-family: 'Montserrat';
  font-weight: 500;
  border-radius: 6px;
  margin-bottom: 3px;
}

.ButtonMain {
  background-color: #e6e6e6;
  position: relative;
  overflow: hidden;
  border: none;
}

.ButtonMain::before,
.ButtonMain::after {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

.ButtonMain span {
  position: relative;
  color: #fff;
}

.ButtonMain:hover span {
  color: #000;
  transition: color 0.3s ease 0s;
}

.BlueRevealEffect::before {
  content: '';
  background: #3a86ff;
  width: 120%;
  left: -10%;
  transform: skew(30deg);
  transition: transform 0.4s cubic-bezier(0.3, 1, 0.8, 1);
}

.BlueRevealEffect:hover::before {
  transform: translate3d(100%,0,0);
}
<button
  class="demo ButtonMain BlueRevealEffect Big"
  onclick="myFunction()">
  <span>Find Out More</span>
</button>
<button
  class="demo ButtonMain BlueRevealEffect Big"
  onclick="myFunction()">
  <span>Find Out More</span>
</button>
<button
  class="demo ButtonMain BlueRevealEffect Big"
  onclick="myFunction()">
  <span>Find Out More</span>
</button>
<button
  class="demo ButtonMain BlueRevealEffect Big"
  onclick="myFunction()">
  <span>Find Out More</span>
</button>

1
  • .querySelector() will return the first matching element. If you want to get an array of all matching elements, use .querySelectorAll(). Commented May 20, 2021 at 16:24

2 Answers 2

1

Pass the element as an argument to the function, using this.

function myFunction(element) {
  let span = element.querySelector("span");
  span.innerHTML = "Copied";
  setTimeout(function() {
    span.innerHTML = "Find Out More";
  }, 1000);
}
.Big {
  width: 257px;
  padding: 33px 0 30px 0;
  font-size: 21px;
}

button {
  font-family: 'Montserrat';
  font-weight: 500;
  border-radius: 6px;
  margin-bottom: 3px;
}

.ButtonMain {
  background-color: #e6e6e6;
  position: relative;
  overflow: hidden;
  border: none;
}

.ButtonMain::before,
.ButtonMain::after {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

.ButtonMain span {
  position: relative;
  color: #fff;
}

.ButtonMain:hover span {
  color: #000;
  transition: color 0.3s ease 0s;
}

.BlueRevealEffect::before {
  content: '';
  background: #3a86ff;
  width: 120%;
  left: -10%;
  transform: skew(30deg);
  transition: transform 0.4s cubic-bezier(0.3, 1, 0.8, 1);
}

.BlueRevealEffect:hover::before {
  transform: translate3d(100%, 0, 0);
}
<button class="demo ButtonMain BlueRevealEffect Big" onclick="myFunction(this)">
  <span>Find Out More</span>
</button>
<button class="demo ButtonMain BlueRevealEffect Big" onclick="myFunction(this)">
  <span>Find Out More</span>
</button>
<button class="demo ButtonMain BlueRevealEffect Big" onclick="myFunction(this)">
  <span>Find Out More</span>
</button>
<button class="demo ButtonMain BlueRevealEffect Big" onclick="myFunction(this)">
  <span>Find Out More</span>
</button>

Sign up to request clarification or add additional context in comments.

Comments

0

You can do this easily by using event-delegation technique (i.e., 1 event listener for many elements) and addEventListener function. This approach allows you to get rid of the inline event handlers in the HTML. See comments in the example for details:

// Store a reference to the div.container
const buttonContainerEl = document.querySelector('#container');

// Add 1 event listener for all 4 buttons
buttonContainerEl.addEventListener('click', event => {
  if (event.target.tagName === 'BUTTON') {
    handleButtonClick(event);
  } else if (event.target.parentElement.tagName === 'BUTTON') {
    event.target.parentElement.click();
  }
});

function handleButtonClick(event) {
  // Store a reference to the clicked button span 
  const spanEl = event.target.querySelector('span');
  // Change the text and set the timeout to reset it
  spanEl.innerHTML = "Copied";
  setTimeout(() => {
    spanEl.innerHTML = "Find Out More";
  }, 1000);
}
.Big {
  width: 257px;
  padding: 33px 0 30px 0;
  font-size: 21px;
}

button {
  font-family: 'Montserrat';
  font-weight: 500;
  border-radius: 6px;
  margin-bottom: 3px;
}

.ButtonMain {
  background-color: #e6e6e6;
  position: relative;
  overflow: hidden;
  border: none;
}

.ButtonMain::before,
.ButtonMain::after {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

.ButtonMain span {
  position: relative;
  color: #fff;
}

.ButtonMain:hover span {
  color: #000;
  transition: color 0.3s ease 0s;
}

.BlueRevealEffect::before {
  content: '';
  background: #3a86ff;
  width: 120%;
  left: -10%;
  transform: skew(30deg);
  transition: transform 0.4s cubic-bezier(0.3, 1, 0.8, 1);
}

.BlueRevealEffect:hover::before {
  transform: translate3d(100%, 0, 0);
}
<div id="container">
  <button class="demo ButtonMain BlueRevealEffect Big">
    <span>Find Out More</span>
  </button>
  <button class="demo ButtonMain BlueRevealEffect Big">
    <span>Find Out More</span>
  </button>
  <button class="demo ButtonMain BlueRevealEffect Big">
    <span>Find Out More</span>
  </button>
  <button class="demo ButtonMain BlueRevealEffect Big">
    <span>Find Out More</span>
  </button>
</div>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.