0
    <head>
    <style>
    .hiddenanswer { display:none;}
    </style>
    </head>
   <body>

    <div id = "allquestions">

    <div class="questions">
    <p> What happens if i want to buy an item </p>
    <p class="hiddenanswer> this cost 600 pounds but we offer dis counts </p>
    </div>

     <div class="questions">
     <p> What happens if i want to buy this item </p>
     <p class="hiddenanswer"> this cost 400 pounds but we offer discounts </p>
     </div>


     <div class="questions">
    <p> What happens if i want to buy a unit </p>
    <p class="hiddenanswer"> this cost 50 pounds but we offer discounts </p>
   </div>

   </div>


<script>


    var para = document.querySelectorAll(" .questions p:nth-child(1)");
    para.addEventListener('click', displayAnswer);


    function displayAnswer () {  
    this.parentNode.lastElementChild.style.display = "block";
   }

  </script>
  </body>

I am in the early learning phase of javascript and really want to come to terms with this. If my understanding is correct , this should work but the browser is not recognising querySelectorAll. I want to achieve a FAQ page on practice project and for the answer to appear once i click on the question.Each answer has a css class which displays them as "none" and when clicking the question, they appear as "block". If i target each P element seperately via document.getElementsByClassNames and selecting my class Node and add an event listener seperately to each of the p elements , it works, but i assumed querySelectorAll should work here so that i wouldnt have to take those lengthy steps. Could it be a problem with my browser or is it a misunderstanding of querySelectorAll on my part ? Thanks all

  • 3
    You’ll need to loop over the collection returned by the querySelectorAll. It’s array-like (but not quite an array) so you can’t just add an event listener to it. – evolutionxbox Jul 24 '20 at 00:29
  • 1
    Does this answer your question? [addEventListener on a querySelectorAll() with classList](https://stackoverflow.com/questions/50643302/addeventlistener-on-a-queryselectorall-with-classlist) – evolutionxbox Jul 24 '20 at 00:29

1 Answers1

0

As others have indicated, adding one listener per question definitely works as long as you loop through the target elements to add the listeners.

Here's a possible alternative employing event delegation, which avoids the need for a loop and provides slightly better performance (unless you have a lot of listeners to add, in which case the performance difference could be significant).

// Selects the outer div
const questionsDiv = document.getElementById("all-questions")

// Calls `displayAnswer` when questionsDiv or something inside it is clicked
questionsDiv.addEventListener('click', displayAnswer);

// Listeners can automatically access events that trigger them
function displayAnswer(event){ 

  // Event objects include a `target` property
  const clickedThing = event.target;
  
  // Makes sure the target is something we care about before proceeding  
  if(clickedThing.classList.contains("trigger")){

    // Changes the `.classList` property, and lets CSS handle the styling 
    clickedThing.nextElementSibling.classList.remove("hidden-answer");
  }
}
.question-container {
  margin-bottom: 10px;
  border: 1px solid lightgrey;
}

.hidden-answer {
  display: none;
}
<div id="all-questions">
  <div class="question-container">
    <p class="trigger"> What happens if i want to buy an item? </p>
    <p class="hidden-answer"> this cost 600 pounds but we offer discounts </p>
  </div>

  <div class="question-container">
    <p class="trigger"> What happens if i want to buy this item? </p>
    <p class="hidden-answer"> this cost 400 pounds but we offer discounts </p>
  </div>

  <div class="question-container">
    <p class="trigger"> What happens if i want to buy a unit? </p>
    <p class="hidden-answer"> this cost 50 pounds but we offer discounts </p>
  </div>
</div>
Cat
  • 4,141
  • 2
  • 10
  • 18