Closure事件委托 - DOM父级上的事件侦听器,它覆盖给定类的子级/后代

Nic*_*ick 7 javascript jquery event-handling event-delegation google-closure

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

$('#j_unoffered').on('click', '.icon_del', function () {...
Run Code Online (Sandbox Code Playgroud)

j_unoffered如果icon_del单击任何带有类的后代元素,则会在触发的元素上放置一个处理程序.此外,它适用于任何后续创建的icon_del元素.

我可以在Closure中正常工作,其中点击是在元素本身上.

goog.events.listen(
    goog.dom.getElement('j_unoffered'),  
    goog.events.EventType.CLICK,
    function(e) {...
Run Code Online (Sandbox Code Playgroud)

我如何在Closure中指定一个父事件目标,它以与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) {...
Run Code Online (Sandbox Code Playgroud)

它仍然this与父母绑定,但e.target允许解决方法.listen(opt_handler)中的第五个参数允许你绑定this到其他东西,所以我猜这也是一个途径.

Ton*_*ony 5

我也不知道这种可能性,所以我建议其他代码:

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

        });
});
Run Code Online (Sandbox Code Playgroud)

用法:

addHandler('#elem', goog.events.EventType.CLICK, '.sub-class', function(e) {
    console.log(e.target);
});
Run Code Online (Sandbox Code Playgroud)

更新:

如果您将使用它e.target.className.indexOf('icon_del'),将有可能错过正确的事件.考虑一个带有id =的容器div container,它有几个带有类的div innerContainer,每个div都包含几个带class =的div finalDiv.并且考虑您将使用上面的代码添加事件处理程序,这将检查e.target的innerContainer类.问题是当用户点击finalDiv你的处理程序时会被调用,但事件目标将finalDivinnerContainer,但不是,但包含它.你的代码会错过它,但不应该.我的代码检查e.target是否有嵌套类或包含它,所以你不会错过这样的事件.

opt_handler 也不能真正帮助你,因为你可能会有许多嵌套元素(你会把它们传递到这里?可能全部,但没有那么有用,你可以随时在事件处理程序中获取它们),而且它们可以在之后动态添加,因此当您添加处理程序时,您无法了解它们.

总而言之,我认为在事件处理程序中完成这样的工作是合理且最有效的.