【问题标题】:Event delegation, why is this not working, selecting target by id事件委托,为什么这不起作用,按 id 选择目标
【发布时间】:2012-07-30 17:54:00
【问题描述】:

编辑#2: 问题不存在了。这是某种范围界定问题。但现在它正在工作。对于给您带来的不便,我深表歉意。


在我的脚本的某些部分,有一个事件委托并通过 id 指定目标。但是当我运行它时。 if(evt.target.id == ("subtaskSubmit" + subtaskCounter)) 行似乎根本不起作用。这是我的代码:

var subtaskCounter = 0;
aWholeTask.addEventListener("click", function(evt){         
            //other event targets specifications ..

                if(evt.target.id == "divide"){  
                    var subtaskInput = document.createElement("input"), 
                    subtaskSubmit = document.createElements.button("submit"), // this is a special function i've made, don't bother about it. I've used it all over the place and it's working normally.
                    subtaskContainer = document.createElement("p");
                    subtaskContainer.style.marginLeft = "40px";
                    subtaskInput.id = "subtaskInput" + (++subtaskCounter);
                    subtaskInput.type = "text";

                    subtaskSubmit.id = "subtaskSubmit" + subtaskCounter;
                    subtaskContainer.appendChildren(subtaskInput,subtaskSubmit);                
                    aWholeTask.appendChild(subtaskContainer);
                }

                if(evt.target.id == ("subtaskSubmit" + subtaskCounter)){
                    //this event is the one that not working when i press on that element
                    alert("hello");                     

                }   
        }); 

编辑: 我做了一些修改来调试代码,结果很奇怪:

  var subtaskCounter = 0;
aWholeTask.addEventListener("click", function(evt){         
            //other event targets specifications ..

                if(evt.target.id == "divide"){  
                    var subtaskInput = document.createElement("input"), 
                    subtaskSubmit = document.createElements.button("submit"), // this is a special function i've made, don't bother about it. I've used it all over the place and it's working normally.
                    subtaskContainer = document.createElement("p");
                    subtaskContainer.style.marginLeft = "40px";
                    subtaskInput.id = "subtaskInput" + (++subtaskCounter);
                    subtaskInput.type = "text";

                    subtaskSubmit.id = "subtaskSubmit" + subtaskCounter;
                    subtaskContainer.appendChildren(subtaskInput,subtaskSubmit);                
                    aWholeTask.appendChild(subtaskContainer);
                }


                    if(evt.target.innerHTML == "Submit"){

                        alert(evt.target.id == ("subtaskSubmit" + subtaskCounter)); 
                        //And this surprisingly returns false !         
                    }   
            });

那么为什么evt.target.id == ("subtaskSubmit" + subtaskCounter) 返回false

【问题讨论】:

  • 为什么要有自调用函数作为事件处理函数?
  • 我只是不希望这两个事件的变量对其余事件可见。
  • 我明白了,还有其他处理程序...每个 id 一个
  • 嗯,不,我的意思是我想将它隐藏在 aWholeTask 点击事件中的任何其他 if(..){..} 语句中。对不起,我有点初学者:)
  • 我的意思是,如果您在 aWholeTask.addEventListener(...) 中有其他自调用函数块,那么它是有意义的

标签: javascript onclick dom-events event-delegation targeting


【解决方案1】:

问题似乎是因为您正在由多个处理程序共享subtaskCounter。对aWholeTask.addEventListener("click", ...) 的调用是否存在循环?

如果有,那么在调用点击处理程序时,subTaskCounter 将始终指向导致它退出循环的值。

示例

var subtaskCounter = 0;
while (subCounter < 5) {
    aWholeTask.addEventListener("click", function(evt){
        console.log(subTaskCounter);
    }); 
    subTaskCounter ++;
}

在上面的示例中,您会注意到subTaskCounter 在调用单击处理程序时始终为 5(导致循环结束的值)。它是所有处理程序共享的同一个变量。如果这确实是您的问题,您需要冻结您的闭包。这是一种方法,使用自调用匿名函数。

var subtaskCounter = 0;
while (subCounter < 5) {
    aWholeTask.addEventListener("click", (function(frozenSubTaskCounter) {
        return function(evt){
            console.log(frozenSubTaskCounter);
        };
    })(subTaskCounter)); 
    // The line above creates a separate closure `frozenSubTaskCounter`
    // for each of the handlers
    subTaskCounter ++;
}

在上面的示例中,您会看到console.log() 将输出您想要的值。

【讨论】:

  • 这正是我正在寻找的,遗憾的是我无法在我正在编写的那个脚本中实现闭包。我想我正在以 OOP 方式重新编写代码。这样就有一个用于添加和删除任务和子任务的功能,我肯定会在那里实现闭包。再次感谢:)
猜你喜欢
  • 2017-05-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-02
  • 1970-01-01
  • 2016-05-01
  • 1970-01-01
  • 2014-01-19
相关资源
最近更新 更多