How to run code when a variable changes in javascript

Viewed 55

I am new to coding and I am trying to figure out how to make my code run when the variable i increases.

The current code executes when i = 1, as defined (.q1). The code also increases the variable i to 2, however, on the next click for .q2, the code doesn't run and I'm not sure why.

Can anyone help explain why the code doesn't run on the next set of buttons (i=2)?

var score = 0
var i = 1

$('.q' + i).on('click', function() {
  if ($(this).is("#correct"))
    $(this).addClass("theright") && ++score;
  else {
    $(this).addClass("thewrong");
  }
  $('.q' + i).attr('disabled', 'disabled') && ++i;
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
  <tr>
    <td><button class=q1 id=correct type="button">option 1</button></td>
    <td><button class=q1 type="button">option 2</button></td>
  </tr>
  <tr>
    <td><button class=q1 type="button">option 3</button></td>
    <td><button class=q1 type="button">option 4</button></td>
  </tr>
</table>

<table>
  <tr>
    <td><button class=q2 type="button">option 1</button></td>
    <td><button class=q2 type="button">option 2</button></td>
  </tr>
  <tr>
    <td><button class=q2 id=correct type="button">option 3</button></td>
    <td><button class=q2 type="button">option 4</button></td>
  </tr>
</table>

2 Answers

You need to register the new click handler for i+1 inside your existing click handler.

var score = 0
var i = 1
        
function registerClick() {
  $('.q'+i).on('click', function(){
    if ($(this).is("#correct"))
      $(this).addClass("theright") && ++score;
    else {
      $(this).addClass("thewrong");
    }
    $('.q'+i).attr('disabled', 'disabled') && ++i;
    // register new click handler for ++i
    registerClick(i);
  })
}
    
registerClick();     

The problem is that your code only once assign a clickHandler for i = 1. So you need to register a new handler every time i is going to change.

Some issues:

  • The main issue is that $('.q' + i).on is only evaluated once, when i is still zero. Although the click handler increases i, this has no effect on anything.

  • In valid HTML you cannot have multiple elements with the same id attribute value, so make "correct" a CSS class instead of an ID.

  • It is bad practice to suffix CSS class names (or id attributes) with a sequential number (like q1, q2). Instead, use one class q and the fact that answers to the same question are grouped in the same table element. You can find the table to which the clicked button belongs, and then find the q elements inside of it.

  • You can then also use one click handler. No more fiddling with + i to create the desired selector.

Here is your corrected snippet:

var score = 0

$('.q').on('click', function() {
  if ($(this).is(".correct")) {
    $(this).addClass("theright") && ++score;
    $("#score").text(score);
  } else {
    $(this).addClass("thewrong");
  }
  $(this).closest("table").find(".q").attr('disabled', 'disabled');
})
.theright { background: green }
.thewrong { background: red }
table { margin: 10px }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
  <tr>
    <td><button class="q correct" type="button">option 1</button></td>
    <td><button class="q" type="button">option 2</button></td>
  </tr>
  <tr>
    <td><button class="q" type="button">option 3</button></td>
    <td><button class="q" type="button">option 4</button></td>
  </tr>
</table>

<table>
  <tr>
    <td><button class="q" type="button">option 1</button></td>
    <td><button class="q" type="button">option 2</button></td>
  </tr>
  <tr>
    <td><button class="q correct" type="button">option 3</button></td>
    <td><button class="q" type="button">option 4</button></td>
  </tr>
</table>

Score: <span id="score">0</span>

Related