代码之家  ›  专栏  ›  技术社区  ›  Jonathon Oates

为什么我不能向引用自身的集合中的每个元素添加事件,而不是向“for(){}”语句中的最后一个元素添加事件

  •  3
  • Jonathon Oates  · 技术社区  · 15 年前

    Window DD 内部元素 Quote_App onCLick 触发函数的事件 Lorem 返回 nodeName Id 的最后一个元素 For 洛雷姆 节点名 身份证件

    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公司 要素 洛雷姆 节点名 身份证件 最后一个 DD公司 元素。

    节点名 Control ( Control[i] )触发了 洛雷姆 .

    非常感谢。

    3 回复  |  直到 15 年前
        1
  •  5
  •   Russ Cam    15 年前

    您需要在循环中附加事件处理程序以捕获 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]);
        })();
      };
    

    需要闭包的原因是,如果没有闭包,则 在上一次循环迭代中,不是我们想要的。我们要的是

    还有一点,虽然有点离题,但它可能会帮助您,那就是并非每个浏览器都支持事件捕获( 啊哼 ,即)但事件冒泡是。这有效地使 useCapture 中的布尔标志 addEventListener

    还有一点,JavaScript通常对函数名和变量名使用camel大小写。Pascal大小写通常只用于构造函数(创建对象的函数)。

        2
  •  3
  •   squelart    15 年前

    当您创建一个引用外部变量的函数时,这些引用将在您调用此函数时解析。

    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)
    

    您要做的是在循环的每一步捕获“i”的值,以便以后进行评估,例如:

    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
    

    您可以看到有一个内部函数,它获取当前计数器的副本作为参数。这个内部函数在该副本中保持活动状态,因此稍后对存储的innest函数的调用将返回创建它的函数的my\u i的值(清除?:-)

    这就是闭包的奇妙世界。首先得到它可能需要一点心血,但之后你会很高兴你做到了,所以去谷歌“javascript闭包”去死吧!

        3
  •  2
  •   Tomalak    15 年前

    这可能是Russ Cam答案的一个更明显的变体:

    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]);
      }
    };