I'm having a problem whereby a loop which is instantiating two objects, which in turn create elements and attach event handlers, only actually attach the event handlers for the last iteration of the loop. While I'm aware of issues with scope inside anonymous functions in a loop, I can't see how that is applicable here, and I'm left scratching my head...
So, first, a setContent method of a view object iterates over an array of content, and creates two instances of the CrowdControl.ui.Button object: (irrelevant code removed for clarity)
setContent: function(content){
if(content.length > 0){
for(var i in content){
var c = content[i];
var container = $('<div></div>');
//content array code removed for clarity
var reject = new CrowdControl.ui.Button({label:'Reject'});
var approve = new CrowdControl.ui.Button({label:'Approve'});
container.append(reject.draw());
container.append(approve.draw());
this.contentlist.addItem(container);
}
}
}
Here is the Button object (again some code removed for clarity)
CrowdControl.ui.Button = function(){
this.uniqueId = Math.random(); //added for debugging
var els = this.elements = {}
els.container = $('<div class="cc-button"></div>');
els.label = $('<div></div>').text('Debug');
els.container.append(els.label);
}
CrowdControl.ui.Button.prototype.draw = function(){
console.log('Drawing element '+this.uniqueId);
var els = this.elements;
els.container.remove();
console.log('Binding click to button');
console.log(els.container);
//attach the click handler - this will only attach during the last iteration
els.container.click( function(){ console.log('wtf'); });
return els.container;
}
The above code logs that all the elements are made, and they're all unique, but only the last two instances of the Button object receive the event ha开发者_StackOverflowndlers and log 'wtf' when clicked.
Any help would be hugely appreciated - if you need any more code or explanation just ask...
I fixed you code: http://jsfiddle.net/maniator/E8XcQ/6/
Click should be done like this:
//attach the click handler
$(els.container).click(function() {
console.log('wtf');
});
You accidentally attached the click
to the DOM element and not the jQuery element
Thanks for the help Neal. It actually turned out the problem was elsewhere in my framework, where a view was incorrectly redrawing after each iteration, and calling .remove() each time, which was of course removing the event handlers from child elements.
精彩评论