Search code examples
jqueryeventsdelegationhandlers

jQuery event delegation with many events and handlers


My question is related to space and readability more so than anything else, but here I go.

I need to use event delegation to get my dynamically added elements working with my jQuery functions. However I'm looking to combine two ways of handling the events. Basically I want this:

$("div").on({
    mouseenter: function() {
        console.log( "hovered over a div" );
    },
    mouseleave: function() {
        console.log( "mouse left a div" );
    },
    click: function() {
        console.log( "clicked on a div" );
    }
});

But I want to use event delegation and have selectors for each event:

$("ul").on("click", "li", function() {
    console.log( "Something in a <ul> was clicked, and we detected that it was an <li> element.");
});

Conclusion: Is it possible to have event delegation when using the first example? Example of what I'd like:

$("div").on({
    mouseenter, 'div': function() {
        console.log( "hovered over a div" );
    },
    mouseleave, 'tr, td, div': function() {
        console.log( "mouse left a div" );
    },
    click, 'td div': function() {
        console.log( "clicked on a div" );
    }
});

Solution

  • Yes it is, but the syntax is a little different and you can't pick and choose selectors for each event

    $('ul').on({
        mouseenter: function() {
            console.log( "hovered over a LI" );
        }, 
        mouseleave: function() {
            console.log( "mouse left a LI" );
        },
        click: function() {
            console.log( "clicked on a LI" );
        }
    }, 'li');
    

    If you really have to filter on different elements for each event you can do something like

    $('div').on({
        mouseenter: function(e) {
            if (e.target.tagName.toLowerCase() === 'tr') {
                console.log( "hovered over a TR" );
            }
        },
        mouseleave: function(e) {
            if (e.target.tagName.toLowerCase() === 'div') {
                console.log( "mouse left a DIV" );
            }
        },
        click: function(e) {
            if (e.target.tagName.toLowerCase() === 'TD') {
                console.log( "clicked on a TD" );
            }
        }
    });
    

    but that's not really any easier than just doing

    $('div').on('mouseenter', 'tr', function() {
         console.log( "hovered over a TR" );
    }).on('mouseleave', 'div', function() {
         console.log( "mouse left a DIV" );
    }).on('click', 'td', function() {
         console.log( "clicked on a TD" );
    });