У меня несколько дел #mydiv1, #mydiv2, #mydiv3, … и хочу назначить им обработчики кликов:

$(document).ready(function(){
  for(var i = 0; i < 20; i  ) {
    $('#question'   i).click( function(){
      alert('you clicked '   i);
    });
  }
});

Но вместо отображения 'you clicked 3' при нажатии #mydiv3 (как и при каждом другом клике) я получаю 'you clicked 20'. Что я делаю неправильно ?

Распространенной ошибкой является создание замыканий в циклах в Javascript. Вам нужна какая-то функция обратного вызова, например:

function createCallback( i ){
  return function(){
    alert('you clicked'   i);
  }
}

$(document).ready(function(){
  for(var i = 0; i < 20; i  ) {
    $('#question'   i).click( createCallback( i ) );
  }
});

Обновление 3 июня 2016 г .: , поскольку этот вопрос все еще набирает обороты, и ES6 также становится популярным, я бы предложил современное решение. Если вы пишете ES6, вы можете использовать ключевое слово let, которое делает переменную i локальной для цикла вместо глобальной: Короче и проще Понимаю.

for(let i = 0; i < 20; i  ) {
  $('#question'   i).click( function(){
    alert('you clicked '   i);
  });
}

Для пояснения, я равен 20, потому что событие click не сработает, пока цикл не завершится.

Вы можете обойтись, назначив обработчик щелчка один раз (или, по крайней мере, не делая много ненужных замыканий). Поместите все элементы div в один класс

$(document).ready(function(){
  for(var i = 0; i < 5; i  ) {
   var $li= $('<li>'   i  '</li>');
      (function(i) {
           $li.click( function(){
           alert('you clicked '   i);
         });
      }(i));
      $('#ul').append($li);
  }
});

, затем: mydivs При этом используется идентификатор элемента для получения его номера с использованием строкового метода

$(document).ready(function(){
    $('.mydivs').click(function(){
        // Get the number starting from the ID's 6th character
        // This assumes that the common prefix is "mydiv"
        var i = Number(this.id.slice(5));

        alert('you clicked '   i);
    });
});

Он просматривает идентификатор элемента, чтобы получить его номер, используя slice. Может быть лучше использовать , это поможет вам каждый раз.

Примечание: вместо чтобы прикрепить обработчик ‘click’, вы можете использовать данные события для передачи ваших данных, например:

$('#divcontainer').on('click', '.mydivs', function(){

Обычно, если вы хотите назначить дескрипторы кликов большому количеству элементов, вы хотите иметь контейнер ( более высокий уровень div), который интерпретирует клики для вас, поскольку клик поднимается вверх от домена.

$('.mydivs').click(function(){

массивов О javascript — Как связать и поделиться предыдущими результатами с Promises — Переполнение стека

for(var i = 0; i < 20; i  ) {
  $('#question'   i).on('click', {'idx': i}, function(e) {
    alert('you clicked '   e.data.idx);
  });
}
//
// let's creat 20 buttons
//

for(var j = 0; j < 20; j  ) {
	$('body').append($('<button/>', {type: 'button', id: 'question'   j, text: 'Click Me '   j}))
}

//
// Passing data to the handler
//
for(var i = 0; i < 20; i  ) {
  $('#question'   i).on('click', {'idx': i}, function(e) {
    console.log('you clicked '   e.data.idx);
  });
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

javascript — Как связать и поделиться предыдущими результатами с Promises

<div id="bucket">
    <span class="decorator-class" value="3">
    ...
</div>

<script>
   $(document).ready(function(e){
      $("#bucket").live('click', function(){
         if(e.target).is('span'){
            alert("elementid: "   $(e.target).val());
         }
      }
   }
<script>