开发者

How to do early binding for event handler in JavaScript? (example with jQuery)

开发者 https://www.devze.com 2022-12-27 13:14 出处:网络
JavaScript\'s late binding is great. But how do I early bind when I want to? I am using jQuery to add links with event handlers in a loop to a div. The variable \'aTag \' changes in the loop. When I

JavaScript's late binding is great. But how do I early bind when I want to?

I am using jQuery to add links with event handlers in a loop to a div. The variable 'aTag ' changes in the loop. When I click the links later, all links alert the same message, which is the last value of 'aTag'. How do I bind a different alert message to all links?

All links should alert with the value that 'aTag' had when the event handler was added, not when it was clicked.

for (aTag in tagList) {
  if (tagList.hasOwnProperty(aTag)) {
    nextTag = $('<a href="#"></a>');
    nextTag.text(aTag);
开发者_开发技巧    nextTag.click(function() { alert(aTag); });
    $('#mydiv').append(nextTag);
    $('#mydiv').append(' ');
  }
}


You can pass data to the bind method:

nextTag.bind('click', {aTag: aTag}, function(event) {
    alert(event.data.aTag);
});

This will make a copy of aTag, so each event handler will have different values for it. Your use case is precisely the reason this parameter to bind exists.

Full code:

for (aTag in tagList) {
  if (tagList.hasOwnProperty(aTag)) {
    nextTag = $('<a href="#"></a>');
    nextTag.text(aTag);
    nextTag.bind('click', {aTag: aTag}, function(event) {
      alert(event.data.aTag);
    });
    $('#mydiv').append(nextTag);
    $('#mydiv').append(' ');
  }
}


You can also make a wrapper function that takes the text to alert as a parameter, and returns the event handler

function makeAlertHandler(txt) {
  return function() { alert(txt); }
}

and replace

nextTag.click(function() { alert(aTag); });   

with

nextTag.click(makeAlertHandler(aTag));


You need to keep a copy of this variable, like this:

for (aTag in tagList) {
  if (tagList.hasOwnProperty(aTag)) {
    nextTag = $('<a href="#"></a>');
    nextTag.text(aTag);
    var laTag = aTag;
    nextTag.click(function() { alert(laTag); });
    $('#mydiv').append(nextTag);
    $('#mydiv').append(' ');
  }
}

The aTag variable is changing each time you loop, at the end of the loop it's left as the last item in the loop. However, each of the functions you created point at this same variable. Instead, you want a variable per, so make a local copy like I have above.

You can also shorten this down a lot with chaining, but I feel it clouds the point in this case, since the issue is scoping and references.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号