Event handler scope in Javascript

后端 未结 3 1339
臣服心动
臣服心动 2021-01-14 10:03

This is probably an easy question but I can\'t figure out the best answer for it.

I have 10

elements on screen. Each of them has a cli
相关标签:
3条回答
  • 2021-01-14 10:13

    You could grab the number from the element's id attribute:

    for ( var i = 0; i < 10; i++ ) {
        var element = document.getElementById( "element" + i );
        element.onclick = function () {
    
            var i = this.id.substr(7);
            alert( "Element " + i );
        }
    }​
    

    JsFiddle here.

    0 讨论(0)
  • 2021-01-14 10:15

    You only have one variable i in an outer scope shared by all your click handlers. You need to create a local variable i for each closure. This will work:

    for ( var i = 0; i < 10; i++ ) {
        var element = document.getElementById( "element" + i );
        element.onclick = (function(i){
            // returns a new function to be used as an onclick handler
            return function () {
                alert( "Element " + i );
            }
        })(i); // Pass in the value of the outer scope i
    }
    

    Check "The Infamous Loop" problem in this article (and read the whole artice) for more information :)

    0 讨论(0)
  • 2021-01-14 10:24

    So your problem is the nature of doing async code inside of loops as the other post said. In your case though there's altogether a better way to solve this problem and that's using event delegation.

    document.body.onclick = function(e) {
      if (e.target.tagName.toLowerCase() === "div") {
        alert( "Element " + e.target.id );
      }
    }
    

    If you had jQuery you could do this:

    $(document.body).on("click", "div", function() {
      alert($(this).attr("id"));
    });
    

    For more info check out this article: http://www.sitepoint.com/javascript-event-delegation-is-easier-than-you-think/

    Obviously jQuery and other libs handle this stuff automatically as well.

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