在 Window
的加载中,Quote_App
中的每个 DD
元素都应该附加一个触发的 onCLick
事件函数 Lorem
,然而,Lorem
返回 For 中最后一个元素的
语句而不是触发函数的元素的语句。我希望 nodeName
和 Id
Lorem
返回触发函数的元素的 nodeName
和 Id
。
function Lorem(Control){
/* this.Control=Control; */
this.Amet=function(){
return Control.nodeName+"\n"+Control.id;
};
};
function Event(Mode,Function,Event,Element,Capture_or_Bubble){
if(Mode.toLowerCase()!="remove"){
if(Element.addEventListener){
if(!Capture_or_Bubble){
Capture_or_Bubble=false;
}else{
if(Capture_or_Bubble.toLowerCase()!="true"){
Capture_or_Bubble=false;
}else{
Capture_or_Bubble=true;
};
};
Element.addEventListener(Event,Function,Capture_or_Bubble);
}else{
Element.attachEvent("on"+Event,Function);
};
};
};
function Controls(){
var Controls=document.getElementById("Quote_App").getElementsByTagName("dd");
for(var i=0;i<Controls.length;i++){
var Control=Controls[i];
Event("add",function(){
var lorem=new Lorem(Control);
lorem.Control=Control;
alert(lorem.Amet());
},"click",Controls[i]);
};
};
Event("add",Controls,"load",window);
目前你点击任何 DD
元素 Lorem
总是返回最后一个 的
元素。nodeName
和 Id
>DD
Lorem
应该返回 Control
的 nodeName
和 Id
(Control[i]
) 触发了 Lorem
。
我该如何着手实现这一目标?
谢谢!
最佳答案
您需要在循环内有一个闭包,您在其中附加事件处理程序以在每次循环迭代中捕获 i
的值。
for(var i=0;i<Controls.length;i++) {
(function() {
var Control=Controls[i];
Event("add",function(){
var lorem=new Lorem(Control);
lorem.Control=Control;
alert(lorem.Amet());
},"click",Controls[i]);
})();
};
我在上面使用 JavaScript 的好 friend 自调用匿名函数创建了一个闭包。
需要闭包的原因是,如果没有闭包,在执行任何事件处理函数时 i
的值将是 i
中的值最后一个循环迭代,不是我们想要的。我们需要 i
的值,因为它在每个循环迭代中,在我们声明每个事件处理函数的点上,因此我们需要在每次迭代中捕获这个值。使用在声明后立即执行的匿名函数是捕获所需值的良好机制。
还有一点,稍微偏离主题但可能对您有所帮助,即并非每个浏览器(ahem,IE)都支持事件捕获,但支持事件冒泡。这有效地使 addEventListener
中的 useCapture
bool 标志对于开发跨浏览器 Web 应用程序非常无用。因此,我建议不要使用它。
还有一点,JavaScript 通常对函数名和变量名使用驼峰式大小写。 Pascal 大小写通常仅用于构造函数(创建对象的函数)。
关于javascript - 为什么我不能将事件添加到引用自身的集合中的每个元素而不是 "for(){}"语句中的最后一个元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2596284/