1

This loop doesn't seem to be working, I'm not sure where i'm going wrong but would appreciate any help.

var j = 0;
for (j = 0; j < 10; j++) {
  $('#btn-' + j).click(function() {
    alert(j);
  });
}
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<button id='btn-0'>One</button>
<button id='btn-1'>Two</button>
<button id='btn-2'>Three</button>
<button id='btn-3'>Four</button>

Basically on the click of the button it should alert out the number the loop is up to (right?) but it just alerts '10' on every one?

It's late and I know I must be doing something wrong, but I can't think what.

Here is a fiddle of my loop: https://jsfiddle.net/p8v5sejr/

Jack Bashford
  • 43,180
  • 11
  • 50
  • 79
FoxyFish
  • 874
  • 1
  • 12
  • 21
  • 3
    Possible duplicate of [JavaScript closure inside loops – simple practical example](https://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example) – Ivar Mar 22 '19 at 01:01

5 Answers5

1

It's because the loop runs, then when you click on your buttons, j is equal to 10. Since your values are coming from the button's IDs, you can use that to your advantage:

var j = 0;
for (j = 0; j < 10; j++) {
  $('#btn-' + j).click(function() {
    alert($(this).attr("id").split("btn-")[1]);
  });
}
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<button id='btn-0'>One</button>
<button id='btn-1'>Two</button>
<button id='btn-2'>Three</button>
<button id='btn-3'>Four</button>
Jack Bashford
  • 43,180
  • 11
  • 50
  • 79
  • No problem whatsoever @FoxyFish - if my answer fixed your problem, please mark it as accepted by clicking the grey tick mark to the left of my answer. – Jack Bashford Mar 22 '19 at 01:11
1

You can grab the id off of the current target element and parse out the index.

for (let index = 0; index < 4; index++) {
  $('#btn-' + index).click(function(e) {
    var value = parseInt(e.target.id.replace(/[\D+]/g, ''), 10);
    alert(value);
  });
}
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<button id='btn-0'>One</button>
<button id='btn-1'>Two</button>
<button id='btn-2'>Three</button>
<button id='btn-3'>Four</button>
Mr. Polywhirl
  • 42,981
  • 12
  • 84
  • 132
1

Try this,

$( "button[id^=btn]" ).each(function(index) {
    $(this).on("click", function(){
        var idvalue = $(this).attr('id'); 

        //alert(index);
        //or
        idvalue = idvalue.replace("btn-","");
        alert(idvalue);
    });
});
1

It's about function scope and block scope

Just use let to declare i in for loop

// var j = 0; <-- Don't use var
for (let j = 0; j < 10; j++) { // <-- use let
  $('#btn-' + j).click(function() {
    alert(j);
  });
}
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<button id='btn-0'>One</button>
<button id='btn-1'>Two</button>
<button id='btn-2'>Three</button>
<button id='btn-3'>Four</button>
bird
  • 1,872
  • 1
  • 15
  • 32
0

If you do the event binding in a function you get a closure keeping the value.

var j = 0;
for (j = 0; j < 10; j++) {
  addClick(j);
}

function addClick(j) {
  $('#btn-' + j).click(function() {
    alert(j);
  });
}
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<button id='btn-0'>One</button>
<button id='btn-1'>Two</button>
<button id='btn-2'>Three</button>
<button id='btn-3'>Four</button>
Adrian Brand
  • 20,384
  • 4
  • 39
  • 60