【问题标题】:How to handle a delegated event for child elements only?如何仅处理子元素的委托事件?
【发布时间】:2012-03-29 09:15:19
【问题描述】:

使用.on 委派事件时如何定位子元素:

我试过了:childSelector =

  • >*
  • >:nth-child(n)

但是当我以> 开头时没有选择任何内容。

$(selector).on(event, childSelector, handler);

有时我想定位一个直接的孩子,有时我不想:(伪代码)

var func = function(selector, subSelector) {
    $(selector).on("click", subSelector, function() {
        alert("my subSelector is clicked");
    });
}

func("#wrapper", "direct-child-selector");
func("#wrapper", ".some .other > .selector:first");

这就是我要求选择器而不是修复的原因。

【问题讨论】:

  • 您的编辑没有任何意义。 child 是一个元素,它是该元素的直接后代......例如child.parentNode === parent。 “indirect child”只是一个后代;例如descendant.parentNode.parentNode.parentNode(etc) === ancestor。由于事件冒泡的工作原理,如果委托处理程序接收到事件,您可以保证事件的目标是后代。
  • @Andreas:查看我的更新答案。

标签: javascript jquery events delegates children


【解决方案1】:

可以在处理程序中检查该元素是否是事件处理程序委托给的元素的子元素;

$(selector).on("event", '*', function (e) {
    if (e.target.parentNode === e.delegateTarget) {
        // Woo!
    }
});

e.delegateTarget。值得注意的是,e.delegateTarget 是在 jQuery 1.7 中引入的,因此不适用于旧版本。

关于您的第二次编辑,在目前的形式中,选择器是模棱两可的;您无法在代码和当前形式中检测传递的选择器是否旨在成为子级选择器。您可以引入另一个参数来指示它是否打算成为子级选择器,或者在选择器的开头添加一个>(例如)并检查它;

var func = function(selector, subSelector, isChild) {
    $(selector).on("click", subSelector, function(e) {
        if (isChild && e.parentNode == e.delegateTarget || !isChild) {
             alert("my subSelector is clicked");
        }
    });
}

func("#wrapper", "direct-child-selector", true);
func("#wrapper", ".some .other > .selector:first" /* , `false` is optional */);

或者:

var func = function(selector, subSelector) {
    if (subSelector.charAt(0) === '>') {
        subSelector = selector + subSelector;
    }

    $(selector).on("click", subSelector, function(e) {
        alert("my subSelector is clicked");
    });
}

func("#wrapper", "> direct-child-selector");
func("#wrapper", ".some .other > .selector:first");

【讨论】:

  • 哇。不知道delicateTarget。但我仍然有问题,请参阅已编辑的问题
  • 好的,感谢您的帮助。因此,似乎没有一个选择器可以保证选择直接子代并为选择其他任何东西腾出空间而没有解决方法。
  • 我认为应该是this.parentNode 而不是e.parentNode。也许e.target.parentNode 也可以。
【解决方案2】:

这对我有用。

$('#container').on('click', '> .children', function(){
...
})

【讨论】:

  • 因为你给孩子们上了特定的课。
【解决方案3】:

仅委托在直接子元素上触发的事件的一种方法是为on() 提供完整的选择器,包括与父元素匹配的部分:

$(selector).on("event", selector + " > *", handler);

【讨论】:

  • W3C 不是将* 定义为“匹配所有元素”吗? w3.org/TR/CSS2/selector.html#pattern-matching
  • @LeeGee,是的,是的。将它与子选择器(例如"div > *")耦合可以匹配给定元素集的所有直接子元素。
【解决方案4】:

你只需要:

childSelector = "*";

如果它应该匹配选择器的任何子项。它只在选择器的范围内搜索。

【讨论】:

  • 这将匹配所有后代。如果元素是 直接 后代,则该元素是子元素。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-09-08
  • 2019-05-16
  • 1970-01-01
  • 1970-01-01
  • 2012-08-15
  • 1970-01-01
  • 2013-08-11
相关资源
最近更新 更多