为什么我不能说是指本身,而不是最后的元素在“为(){}”语句集合中的事件添加到每个元素

StackOverflow https://stackoverflow.com/questions/2596284

Window的负荷,内部DDQuote_App元素应该有一个onCLick事件附属触发功能Lorem,然而,Lorem返回在nodeName声明Id和最后一个元素的For而不是该触发功能的元素。我想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单击总是返回最后nodeName元素的IdDD

Lorem应返回nodeNameId)触发ControlControl[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的好朋友,自调用匿名函数闭包。

需要关闭的原因是,如果没有它,i在在此的任何事件处理函数执行将i在最后循环迭代值的点值,不是我们想要的。我们希望i的价值,因为它是在每次循环迭代,以在我们宣布每个事件处理函数的地步,因此,我们需要捕获在每次迭代此值。执行,只要它被声明是使用匿名功能良好的机构,用于捕获所希望的值。

另外一点,稍微偏离主题,但它可以帮助你,是该事件捕捉并不在每个浏览器支持的(啊哈的,IE浏览器),但事件冒泡是。这实际上使得useCaptureaddEventListener布尔标志用于开发跨浏览器Web应用程序很没用。因此我建议不使用它。

一两件事,JavaScript的通常使用骆驼壳体为函数名和变量名。帕斯卡壳体一般只用于构造函数(创建对象的函数)。

其他提示

当您创建引用变量之外它的功能,这些引用将在调用此函数的时间解决。

在你的情况:

var functions = [];
function outer() {
    for (var i = 0; i < N; i++) { // <------------
        functions[i] = function() { //            |
            alert(i); // <-- this 'i' refers to this one
        }
    } // At the end of the for loop, i == N (or N+1?)
}
functions[x](); // Will show N (or N+1)
// because that's the current value of i in the outer function
// (which is kept alive just because something refers to it)

您想要做的是捕获的“我”在循环的每一步的价值,为以后的评价,e.g:

var functions = [];
function outer() {
    for (var i = 0; i < N; i++) { // <---------------------------------------
        functions[i] = (function(my_i) { // <----                            |
            return function () { //              |                           |
                alert(my_i); // my_i refers to this which is a copy of 'i' there
            }
        }(i)); // run function(with my_i = the i at each step of the loop)
    }
}
functions[x](); // Will show x

可以看到存在这样获取当前计数器的副本作为参数的内功能。这种内在的功能保持活着与副本,以便以后调用创建它的功能my_i的存储innest函数返回值 - 清除? : - )

这是封闭的奇妙世界。这可能需要一点令人费解先得到它的,但你会很高兴你没有,所以去和谷歌“的JavaScript倒闭潮”到死!

这可以是拉斯凸轮的回答的更明显的变体:

function Controls() {
  var Controls = document.getElementById("Quote_App").getElementsByTagName("dd");

  var createHandlerFor = function(CurrentControl) {
    return function() {
      var lorem=new Lorem(CurrentControl);
      lorem.Control=CurrentControl;
      alert(lorem.Amet());
    }
  };

  for (var i=0; i<Controls.length; i++) {
    Event("add", createHandlerFor(Controls[i]), "click", Controls[i]);
  }
};
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top