Search code examples
jqueryecmascript-6arrow-functions

jQuery and ES6 arrow functions


In jQuery we are used to binding click handlers like this:

$(".all-buttons").click(function() {
    var btn = this;
    console.log(btn.innerHTML);
});

I would like to be able to use the same functionality with ES6 arrow functions like this:

$(".all-buttons").click(btn => console.log(btn.innerHTML));

The issue is that jQuery doesn't pass the current element as an argument like other native javascript functions do, for example Array.forEach()

Another issue is that arrow functions cannot be "applied" i.e. called like fn.apply(this, args), which is what jQuery relies on for letting me know which element triggered the event.

I just put the "click" example here, but I would like to be able to apply this to any jQuery callback.

Does anybody have any suggestions about how to achieve this? perhaps to use a different library that does call my callbacks with the element as an argument? or perhaps a jquery plugin? or a javascript trick I don't know about?

I appreciate the help.


Solution

  • The basic functionality is trivial: The Event object the handler receives has a currentTarget property which is the same as this:

    $(".all-buttons").click(e => console.log(e.currentTarget.innerHTML));
    

    Note this is not the same as e.target:

    • target is the element the event is targeted at, whereas
    • currentTarget is the element the event is passing through on en route to that target on which this handler was hooked

    So for instance, if you have

    <div>
        <span>click me</span>
    </div>
    

    ...and you have a handler hooked to that div, clicking the span will give you e.target = the span, e.currentTarget = the div.

    Regarding "other libraries," library recommendations are off-topic for SO. But I'll note that on modern browsers:

    • The NodeList returned by the DOM's own querySelectorAll has forEach, which makes it easy to loop over matches (it's also trivial to polyfill on any vaguely-recent browser)
    • DOM elements also now have a closest method which makes event delegation with the DOM much simpler than it used to be (and again, can be polyfilled).