Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle a delegated event for child elements only?

When delegating events using .on how do I target child elements:

I have tried: childSelector =

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

But nothing is selected when I start with >.

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

Sometimes I want to target a direct child, sometimes I don't: (pseudo code)

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

Thats why I'm asking for a selector and not a fix.

like image 212
Andreas Louv Avatar asked Mar 29 '12 09:03

Andreas Louv


1 Answers

You could check within the handler whether the element is a child of the element the event handler was delegated to;

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

See e.delegateTarget. Its worthy to note that e.delegateTarget was introduced in jQuery 1.7, so won't work on older versions.

In regards to your second edit, in it's current form the selectors are ambiguous; there's no way for you to, in code and in its current form, detect whether the selector passed is intended to be a child only selector. You can either introduce another parameter to indicate whether it's intended to be a child only selector, or add a > to the start of the selector (e.g.) and check for that;

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

Or:

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");
like image 55
Matt Avatar answered Oct 14 '22 15:10

Matt