javascript - 为什么我不能将事件添加到引用自身的集合中的每个元素而不是 "for(){}"语句中的最后一个元素

标签 javascript foreach addeventlistener getelementsbytagname

Window 的加载中,Quote_App 中的每个 DD 元素都应该附加一个触发的 onCLick 事件函数 Lorem,然而,Lorem 返回 For 中最后一个元素的 nodeNameId 语句而不是触发函数的元素的语句。我希望 Lorem 返回触发函数的元素的 nodeNameId

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 总是返回最后一个 nodeNameId >DD 元素。

Lorem 应该返回 ControlnodeNameId (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/

相关文章:

javascript - 为什么单个 document.write 语句同时加载 jquery 缩小文件和完整的 jquery 文件?

javascript - 全日历日点击返回错误日期

foreach - 新旧 foreach 循环

php - 如何在 PHP 中使用 foreach 循环设置多个复选框中的选定属性?

javascript - 添加事件监听器不是带有queryselector的函数

javascript - URL 自动附加到页面 URL

javascript - 如何在 jQuery 中确定和设置窗口的高度和滚动位置?

java - 并排打印 csv 中的两个数组

Javascript - 通过 ID 获取元素的简写方法

reactjs - 如何在 Gatsby 中捕获 document.ready 或 window.load 事件