我遇到一个问题,即一个实例化两个对象的循环,它反过来创建元素并附加事件处理程序,实际上只是为循环的最后一次迭代附加了事件处理程序。虽然我知道循环中匿名函数内部的范围问题,但是我看不出这是如何适用的,而且我还在摸不着头脑......
因此,首先,视图对象的setContent方法迭代内容数组,并创建CrowdControl.ui.Button对象的两个实例:(为清晰起见,删除了不相关的代码)
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);
}
}
}
这是Button对象(为清晰起见,还删除了一些代码)
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;
}
上面的代码记录了所有元素的构成,它们都是唯一的,但只有Button对象的最后两个实例接收事件处理程序并在单击时记录'wtf'。
非常感谢任何帮助 - 如果您需要更多代码或解释,请询问......
答案 0 :(得分:2)
我修改了代码:http://jsfiddle.net/maniator/E8XcQ/6/
点击应该像这样:
//attach the click handler
$(els.container).click(function() {
console.log('wtf');
});
您不小心将click
附加到DOM元素而不是jQuery元素
答案 1 :(得分:0)
感谢Neal的帮助。它实际上证明问题出现在我的框架中,其中每次迭代后视图都不正确地重绘,并且每次调用.remove(),这当然是从子元素中删除事件处理程序。