0

I am trying to create a very simple form. My objective is to create two clickable buttons, each containing a question. When clicked, the DOM will output the answer below the each button. The tricky part is getting both buttons to respond with only one addEventListener. Here is my code:

HTML:

    <div id="wrapper">
    <header>
        <h1>Have you ever wondered...</h1>
    </header>
    <div>
        <button id="myBtn">How many licks it takes to get to the center of a tootsie pop?</button>

        <p id="first"></p>

        <h3>Or what about...</h3>

        <button id="myBtnTwo">How tall the Eiffel Tower is?</button>

        <p id="second"></p>

    </div>
</div>

JS:

document.getElementById("myBtn").addEventListener("click", function(){
    document.getElementById("first").innerHTML= "Approximately 364 licks!";    

    });

document.getElementById("myBtnTwo").addEventListener("click", function(){
    document.getElementById("second").innerHTML= "984 feet!";
});
3
  • A handler can only be pointed to a single element in JS. You can however assign more than one handler to an element. Just not the other way around. Each one of your buttons needs its own handler. Commented Nov 8, 2016 at 16:30
  • See this previous question on stackoverflow. Commented Nov 8, 2016 at 16:31
  • If you want to execute the same code for each button maybe you can simply use inline onclick handler for both buttons like: <button id="myBtn" onclick="yourFunction()"> <button id="myBtnTwo" onclick="yourFunction()"> Commented Nov 8, 2016 at 16:38

3 Answers 3

1

You can only bind one element to every event listener in JS. However, you can have multiple different events associated with one element.

Now, to solve your question: One way to address this situation is to attach the event handler to the parent element and then find the element that was the target of the event.

<div id="wrapper">
  <header>
    <h1>Have you ever wondered...</h1>
  </header>
<div id="btn-wrapper">
  <button id="myBtn">How many licks it takes to get to the center of a tootsie pop?</button>
  <p id="first"></p>
  <h3>Or what about...</h3>
  <button id="myBtnTwo">How tall the Eiffel Tower is?</button>
  <p id="second"></p>
</div>

As you can see, I added the id btn-wrapper to the parent div. And then in the JS, I attached the handler to said parent element. Then you can find the event target and run your code according to which it was.

var theParent = document.querySelector("#btn-wrapper");
theParent.addEventListener("click", doSomething, false);

function doSomething(e) {
    if (e.target !== e.currentTarget) {
            if (e.target === document.querySelector('#myBtn')) {
        document.querySelector("#first").innerHTML= "Approximately 364 licks!"; 
      } else if (e.target === document.querySelector('#myBtnTwo')) {
        document.querySelector("#second").innerHTML= "984 feet!";
      }
    }
    e.stopPropagation();
}

To read some more on the topic: https://www.kirupa.com/html5/handling_events_for_many_elements.htm

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

1 Comment

That helps a bunch, thank you for the detailed response!
0

You can add a listener for the container div and then check which element is clicked:

document.querySelector('#container').addEventListener('click', (e) => {
  if (e.target.id === 'myBtn') {
    document.querySelector('#first').innerText = 'answer 1'
  }
  
  if (e.target.id === 'myBtnTwo') {
    document.querySelector('#second').innerText = 'answer 2'
  }
})
<div id="wrapper">
    <header>
        <h1>Have you ever wondered...</h1>
    </header>
    <div id='container'>
        <button id="myBtn">How many licks it takes to get to the center of a tootsie pop?</button>

        <p id="first"></p>

        <h3>Or what about...</h3>

        <button id="myBtnTwo">How tall the Eiffel Tower is?</button>

        <p id="second"></p>

    </div>
</div>

Comments

0
const findBtns = [...document.querySelectorAll("button")];
const handleClick = (event) => {
    console.log(event.target.textContent);
};
findBtns.forEach((el) => el.addEventListener("click", handleClick));

You can just simply use another selector (.querySelectorAll) and work with the pseudo array further. If you just need to extract the text from a button it is better to use /.textContent/. /.innerHTML/ could be harmful if you not 100% sure that you need it in your code.

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.