Javascript 闭包事件委派-DOM父级上的事件侦听器,涵盖给定类的子级/子级

Javascript 闭包事件委派-DOM父级上的事件侦听器,涵盖给定类的子级/子级,javascript,jquery,event-handling,google-closure,event-delegation,Javascript,Jquery,Event Handling,Google Closure,Event Delegation,在jQuery中,可以执行以下操作: $('#j_unoffered').on('click', '.icon_del', function () {... 这将在元素j_unoffered上放置一个处理程序,如果单击任何具有类icon\u del的子元素,该处理程序将触发。此外,它还适用于随后创建的任何图标\u del元素 我可以在元素本身上单击的闭包中很好地实现这一点 goog.events.listen( goog.dom.getElement('j_unoffered'),

在jQuery中,可以执行以下操作:

$('#j_unoffered').on('click', '.icon_del', function () {...
这将在元素
j_unoffered
上放置一个处理程序,如果单击任何具有类
icon\u del
的子元素,该处理程序将触发。此外,它还适用于随后创建的任何
图标\u del
元素

我可以在元素本身上单击的闭包中很好地实现这一点

goog.events.listen(
    goog.dom.getElement('j_unoffered'),  
    goog.events.EventType.CLICK,
    function(e) {...
我如何在闭包中指定一个父事件目标,并以与jQuery示例相同的方式为其子/子体工作

我假设我需要以某种方式使用
setParentEventTarget
,但我不确定如何为DOM事件实现它。我发现的大多数文档都与自定义分派事件有关

--更新--

我想知道这个相当简单的解决方案是否有问题:

goog.events.listen(
    goog.dom.getElement('j_unoffered'),  
    goog.events.EventType.CLICK,
    function(e) {
        if (e.target.className.indexOf('icon_del') !== -1) {...

它仍然将
绑定到父级,但
e.target
允许解决此问题。
listen
(opt_handler)中的第五个参数允许您将
绑定到其他对象,因此我想这也是一种途径。

您所指的是

这是不可能的(开箱即用)谷歌关闭库;因此,我建议使用jQuery或其他类似的事件处理库来提供此功能。如果这是不可能的,或者如果您想手工完成,这里有一种可能的方法(注意:这不是用于生产)

var delegateClick=function(containerId、childrenClass、handler){
listen(goog.dom.getElement(containerId)、goog.events.EventType.CLICK、函数(event){
var target=event.target;
//console.log(事件);
while(目标){
if(target.className&&target.className.split(“”).indexOf(childrenClass)!=-1){
打破
}
target=target.parentNode;
}
如果(目标){
//如果仍有目标,则处理事件
调用(目标、事件);
}
});
}
//然后使用它,在这里尝试:http://closure-library.googlecode.com/git/closure/goog/demos/index.html
//..选择导航上下文
delegateClick('demo list','goog-tree-icon',函数(事件){console.log(事件);})
这里有一个更深入的分析


同样,您应该为此使用一个经过验证的库,这里有一些选项:,

我也不知道这种可能性,因此我建议使用其他代码:

var addHandler = function(containerSelector, eventType, nestSelector, handler) {
    var parent = goog.isString(containerSelector) ? 
                 document.querySelector(containerSelector) :
                 containerSelector;

    return goog.events.listen(
        parent,
        eventType,
        function(e) {

            var children = parent.querySelectorAll(nestSelector);
            var needChild = goog.array.find(children, function(child) {
                return goog.dom.contains(child, e.target);
            });

            if (needChild)
                handler.call(needChild, e);                

        });
});
用法:

addHandler('#elem', goog.events.EventType.CLICK, '.sub-class', function(e) {
    console.log(e.target);
});
更新

如果使用此
e.target.className.indexOf('icon_del')
可能会错过正确的事件。考虑一个容器div,ID为“代码=代码>容器< /代码>,它有两个div类,它们是类<代码>内纳容器< /代码>,每个div包含两个div类,这些类具有类=代码> FialDdiv < /代码>。并且考虑您将添加上面的代码的事件处理程序,它将检查E.Talk用于<代码>内纳容器类。问题是当用户单击
finalDiv
时,您的处理程序将被调用,但事件目标将是
finalDiv
,它不是
innerContainer
,而是由它包含的。您的代码将丢失它,但它不应该丢失。我的代码检查e.target是否有嵌套类或包含在其中,这样您就不会错过此类事件

opt_handler
也不能真正帮助您,因为您可能需要处理许多嵌套元素(您将在此处传递其中的哪一个?可能全部,但不是很有用,您可以随时在事件处理程序中获取它们),而且它们可以在之后动态添加,因此当您添加处理程序时,您无法了解它们


总之,我认为在事件处理程序中执行这样的工作是合理和最有效的。

感谢
事件委派
术语。我使用它;我只是不记得它叫什么:)我认为认为认为闭包不是一个“经验证的库”是一个很长的问题+但这是一个好的开始。也请看我的更新。@Nick我建议为事件处理/委派提供一个经验证的库(任何库),而不是您自己的库。我并不是说闭包不是个好主意。问候:)你好。你为什么说“这不是生产用的”?+1是一个好的开始,但我相信谷歌员工以前一定遇到过这种情况,所以我很高兴能重新发明轮子。请看我的更新。@Nick让我们看一些演示:(我不得不稍微更改代码,因为JSFIDLE中没有闭包,但方法是一样的)。尝试单击不同的项目,看看会发生什么。我想第二种方法更正确。是的,它是有效的,但据我所知,你需要更通用的方法。我从演示中删除了对调用的
,并使用了
addEventListener
。它的工作原理相同:。我相信您需要像我的代码一样在这里进行dom遍历。它无法识别
span
的原因是
e.target
a
!!尝试
console.log(e.target):)我知道!这正是我想展示的。您问这个简单的解决方案有什么问题,我演示了在某些情况下它不起作用,代码需要更复杂,这不是您想要的吗?