代码之家  ›  专栏  ›  技术社区  ›  Philip

在for循环中分配单击处理程序

  •  70
  • Philip  · 技术社区  · 15 年前

    #mydiv1 , #mydiv2 , #mydiv3

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

    但不是表现出来 'you clicked 3' 当点击 (至于每一次点击)我得到 'you clicked 20' . 我做错什么了?

    6 回复  |  直到 12 年前
        1
  •  132
  •   Harmen    8 年前

    这是一个常见的错误 closures in loops

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

    2016年6月3日更新: 由于这个问题仍然得到一些牵引力和ES6也越来越流行,我建议一个现代的解决方案。如果你写ES6,你可以使用 let 关键字,使 i

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

    它更短,更容易理解。

        2
  •  12
  •   Donald    15 年前

    为了澄清,我等于20,因为在循环完成之前,单击事件不会触发。

        3
  •  7
  •   user1490857    13 年前
    $(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);
      }
    });
    
        4
  •  4
  •   PleaseStand    13 年前

    您可以只分配一次click处理程序(或者至少不创建许多不必要的闭包)。把所有的div放在一个类中 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 string method

    注: 用它可能更好

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

    而不是

    $('.mydivs').click(function(){
    
        5
  •  4
  •   gaetanoM    9 年前

    on 要附加“click”处理程序,可以使用事件数据来传递数据,如:

    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>
        6
  •  2
  •   stancoffyn    15 年前

    <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>