Assign click handlers in for loop

前端 未结 6 2110
野的像风
野的像风 2020-11-22 03:21

I\'m having several div\'s #mydiv1, #mydiv2, #mydiv3, ... and want to assign click handlers to them:

$(document).ready         


        
相关标签:
6条回答
  • 2020-11-22 03:26
    $(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);
      }
    });
    
    0 讨论(0)
  • 2020-11-22 03:26

    You can get by with assigning the click handler once (or at least not making many unnecessary closures). Put all the divs in one class mydivs, then:

    $(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);
        });
    });
    

    This looks at the element's ID to get its number, using the slice string method to strip the initial letters off.

    Note: It may be better to use

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

    instead of

    $('.mydivs').click(function(){
    
    0 讨论(0)
  • 2020-11-22 03:40

    To clarify, i is equal to 20 because the click event won't have fired until after the loop has finished.

    0 讨论(0)
  • 2020-11-22 03:44

    It's a common mistake to create closures in loops in Javascript. You need to have some sort of callback function like this:

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

    Update June 3, 2016: since this question is still getting some traction and ES6 is getting popular as well, I would suggest a modern solution. If you write ES6, you can use the let keyword, which makes the i variable local to the loop instead of global:

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

    It's shorter and easier to understand.

    0 讨论(0)
  • 2020-11-22 03:44

    Generally, if you are looking to assign click handles to a large number of items, you want to have a container (higher level div) that interprets the clicks for you, as the click bubbles up from the dom.

    <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>
    
    0 讨论(0)
  • 2020-11-22 03:50

    Using on to attach the 'click' handler you can use the event data in order to pass your data like in:

    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>

    0 讨论(0)
提交回复
热议问题