skip to Main Content

I’m attempting to make a flashcard type of web app. Each question is in an h2 and each answer is in a p. I want the answer to initially be hidden and to be revealed when a user clicks the question h2, so I added a data-question-obj-id="{{question.id}}" (django project, {{question.id}} evaluates to positive integer so 1,2,3,etc) attribute to both to know which question is associated with which answer. However, I am struggling to get the data-attribute portion to work:

Say I had the following html:

  <h2 data-question-obj-id="1">What is Diffusion?</h2> 
  <p data-question-obj-id="1">Spontaneous movement of particles...</p>
  <h2 data-question-obj-id="2">What is Osmosis?</h2> 
  <p data-question-obj-id="2">Spontaneous passage or diffusion of water or...</p>

In my js, I am attempting to get all questions then loop through them and add a click event to each one that logs the clicked questions data-question-obj-id attribute value to the console, but it is logging the same attribute value for every question:

questions = document.querySelectorAll('h2[data-question-obj-id]');

for (let i = 0; i < questions.length; i++) {
  question = questions[i];
  console.log(question); // Sanity check, outputs <h2 data-question-obj-id="1">Diffusion</h2> then <h2 data-question-obj-id="2">Osmosis</h2> as expected
  question.addEventListener('click', function(){
    console.log(question.getAttribute("data-question-obj-id")); // Will output '2' not matter what question is clicked
  });

}

For brevity I only included two question/answer combinations but if I had three, that console.log(question.getAttribute("data-question-obj-id")); would output 3 for any question clicked, so it seems to always be getting the value of the last element? Thanks for any help with this.

2

Answers


  1. You can preload the answers too and when you loop the questions with your index, you can use the index to infer the corresponding answer too. I have made sure the answer is initially hidden and clicking on the question toggles the appearance of the answer.

    let questions = document.querySelectorAll('h2[data-question-obj-id]');
    let answers = document.querySelectorAll('p[data-question-obj-id]');
    
    for (let i = 0; i < questions.length; i++) {
      let question = questions[i];
      let answer = answers[i]
      question.addEventListener('click', function(){
        console.log(question.getAttribute("data-question-obj-id")); // Will output '2' not matter what question is clicked
        answer.classList[(answer.classList.contains('invisible') ? 'remove' : 'add')]('invisible');
      });
    }
    .invisible {
        display: none;
    }
      <h2 data-question-obj-id="1">What is Diffusion?</h2> 
      <p data-question-obj-id="1" class="invisible">Spontaneous movement of particles...</p>
      <h2 data-question-obj-id="2">What is Osmosis?</h2> 
      <p data-question-obj-id="2" class="invisible">Spontaneous passage or diffusion of water or...</p>
    Login or Signup to reply.
  2. Here is a different approach (in vanilla ecmascript).

    First: wrap question and answer within a div containing the obj-question-id data attribute. Second: use event delegation to handle any question with one handler (identifying the question id using [event.target].closest). For displaying the question, itm may be an idea to use css (used nested css in the snippet for mousedown-like effect).

    document.addEventListener(`click`, handle);
    
    function handle(evt) {
      const questionBlock = evt.target.closest(`[data-question-obj-id]`);
      
      if (questionBlock) {
        console.clear();
        const question = questionBlock.firstElementChild;
        return console.log(`[data-question-obj-id] = ${
          questionBlock.dataset.questionObjId}`);
      }
    }
    div[data-question-obj-id] {
      h2 { margin: 0.2em; }
      div { display: none; }
      &:active {
        div {
          display: block;
          color: #777;
          margin-left: 2em;
        }
      }
      cursor: pointer;
    }
    <div data-question-obj-id="1"> 
      <h2>What is Diffusion?</h2>
      <div>Spontaneous movement of particles...</div>
    </div>
    <div data-question-obj-id="2"> 
      <h2 >What is Osmosis?</h2>
      <div>Spontaneous passage or diffusion of water or...</div>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search