0

Ultimately, my objective here is to create a JS script where I can use for my quizzes. In a page, I may put more than one item. In this regard, I will have more than one button, one button per item. What you see here is a prototype. (I wanted to see how each element interacts with one another.) In the process of trying to get it work, I looked over what others have done. However, I came to a point where I am stuck and could not see what I am doing wrong. I have a sense of where the problem is but I am not certain of it. Anyway, please see where my mistakes are and let me know.

This is the html part. What I want to happen here is I click the top button and the background of the text, "Hello" at top turns red. I press the middle and the text background turn red, and so on. Currently, I press any button and they all turn red.

<div class="q">
  <div class="p">
    <p>Hello</p>
  </div>
  <button>Show Answer</button>
</div>
<div class="q">
  <div class="p">
    <p>Hello</p>
  </div>
  <button>Show Answer</button>
</div>
<div class="q">
  <div class="p">
    <p>Hello</p>
  </div>
  <button>Show Answer</button>
</div>

The link to the js script is located in the head section.

<script src="../js/s3.js"></script>

Here is the js. I suspect my mistake is in the second half. The reason for this is that I made the var in the second for the same as in the first one and still got the same result. It made me wonder whether if the computer is ignoring this part. I could be wrong. I tried querySelectorAll and the result is the same as well. By the way, when is it advantageous to use querySelectorAll and getElementsByClassName if class is involved?

window.onload = function () {
  let c = document.getElementsByClassName('q');
  for (var ii = 0; ii < c.length; ii++) {
    c[ii].addEventListener('click', function () {
    let a = document.getElementsByClassName('p');
  for (var i = 0; i < a.length; i++) {
    a[i].classList.add('cellRed');
   }
  });
 } 
}

Here is the CSS.

.cellGreen {
    background-color: green;
    color: white;
}

.cellRed {
    background-color: red;
    color: white;
}

I was told to keep things separate. So I did.

1
  • Welcome to Stack Overflow. When posting questions, please try to refrain from conversational material, especially if you are trying to ward off unhelpful or snarky responses. Unfortunately asking people to be kind (or not to downvote etc) usually results in the response you least want to see. In any case, we ask that posts are written using neutral, technical language here, so chatty material is discouraged anyway. Think of your question (and its answers) as forming documentation that will last forever. Commented Nov 10, 2019 at 22:48

3 Answers 3

2

First thing you should do when tackling a problem is to think about what you're trying to accomplish. It really does help to list it in steps.

  • In every Question div
    • Get the Button
    • Get the Paragraph
    • When the Button is clicked
      • Turn the Paragraph Red

This allows us to build our code rather simply from step 1 onward. This isn't always perfect, but it is always helpful.


Get All Questions

let questions = document.querySelectorAll(".q");

For Each Question

questions.forEach(question => {

    // ... do something

});

Get the Button

questions.forEach(question => {

  let btn = question.querySelector("button");

});

Get the Paragraph

questions.forEach(question => {

  let btn = question.querySelector("button");
  let p = question.querySelector("p");

});

When the Button is Clicked

questions.forEach(question => {

  let btn = question.querySelector("button");
  let p = question.querySelector("p");

  btn.addEventListener("click", function() { 

     // ... do something

  });

});

Turn the Paragraph Red

questions.forEach(question => {

  let btn = question.querySelector("button");
  let p = question.querySelector("p");

  btn.addEventListener("click", function() { 

     p.classList.add("cellRed");

  });

});

Final Example:

window.onload = function() {
  let questions = document.querySelectorAll(".q");

  questions.forEach(question => {
    let btn = question.querySelector("button");
    let p = question.querySelector("p");

    btn.addEventListener("click", function() {
      p.classList.add('cellRed');
    });
  })
}
.cellGreen {
  background-color: green;
  color: white;
}

.cellRed {
  background-color: red;
  color: white;
}
<div class="q">
  <div class="p">
    <p>Hello</p>
  </div>
  <button>Show Answer</button>
</div>
<div class="q">
  <div class="p">
    <p>Hello</p>
  </div>
  <button>Show Answer</button>
</div>
<div class="q">
  <div class="p">
    <p>Hello</p>
  </div>
  <button>Show Answer</button>
</div>

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

1 Comment

THANK YOU! I like the way you approach the task. I will adopt that approach when writing codes. I later realized I was getting more and more confused that led to frustration. This way, it would remind me what I am trying to achieve. Secondly, after looking what you have written, I was nowhere near a solution. More ways to go for me. Again, much appreciated.
0

That second loop is unnecessary. Just use let instead of var in first loop.

According to MDN:

let allows you to declare variables that are limited in scope to the block, statement, or expression on which it is used. This is unlike the var keyword, which defines a variable globally, or locally to an entire function regardless of block scope.

Look at example below:

window.onload = function () {
  let c = document.getElementsByClassName('q');
  for (let i = 0; i < c.length; i++) {
    c[i].addEventListener('click', function () {
    let a = document.getElementsByClassName('p');
    a[i].classList.add('cellRed');
  });
 } 
}
.cellGreen {
    background-color: green;
    color: white;
 }

.cellRed {
    background-color: red;
    color: white;
  }
<div class="q">
<div class="p">
<p>Hello</p>
</div>
<button>Show Answer</button>
</div>
<div class="q">
<div class="p">
<p>Hello</p>
</div>
<button>Show Answer</button>
</div>
<div class="q">
<div class="p" >
<p>Hello</p>
</div>
<button>Show Answer</button>
</div>`

1 Comment

Thank you for your comments. I am still confused with the let, const, and var. I am not sure when to use it although I have been told the differences of each one. Still, more practice. Second, I suspect there was something about the second loop. It just never occurred to me to delete it. Third, looking at how you improved my codes and connexo's codes, it was wrong for me to say that I was far off, but it made me realize there are different ways in approaching a task. I just need to learn more "vocabs." Thanks again.
0

I know you want help with your javascript code, but others have already helped you, so I mostly wanted to show that this can be solved with pure CSS only without javascript. :) I'm basically using radio-buttons and sibling selector.

div.p > p {
  margin-bottom: 0;
}

div.p > input {
  display: none;
}

div.p > label {
  cursor: pointer;
  font-size: 90%;
  margin-right: 1rem;
}

div.p > input:checked ~ p {
    color: white;
    background-color: red;
}

div.p > input:checked[value="correct"] ~ p {
    background-color: green;
}
<div class="q">
  <div class="p">
    <input type="radio" name="q1" id="q1_alt1" value="correct" />
    <input type="radio" name="q1" id="q1_alt2" />

    <p>Hello</p>
  
    <label for="q1_alt1">Answer 1</label>
    <label for="q1_alt2">Answer 2</label>
  </div>
</div>

<div class="q">
  <div class="p">
    <input type="radio" name="q2" id="q2_alt1" />
    <input type="radio" name="q2" id="q2_alt2" value="correct" />

    <p>Hello</p>

    <label for="q2_alt1">Answer 1</label>
    <label for="q2_alt2">Answer 2</label>
  </div>
</div>

<div class="q">
  <div class="p">
    <input type="radio" name="q3" id="q3_alt1" />
    <input type="radio" name="q3" id="q3_alt2" />
    <input type="radio" name="q3" id="q3_alt3" value="correct" />

    <p>Hello</p>
  
    <label for="q3_alt1">Answer 1</label>
    <label for="q3_alt2">Answer 2</label>
  <label for="q3_alt3">Answer 3</label>

  </div>
</div>

1 Comment

I find your take interesting. I am also learning CSS. I did not know this was possible. I will test this way as well. Thank you very much. I appreciate you taking the time writing it down.

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.