Skip to content

Improved currentTarget

chemerisuk edited this page Oct 9, 2014 · 4 revisions

One of the extremely useful things in jQuery is ability to filter events by a CSS-selector. This feature allows to filter cases when an event is happened on particular DOM elements:

<ul id="menu">
    <li><a href="page1.html">Page1</a></li>
    <li><a href="page2.html">Page2</a></li>
    ...
</ul>
...
<script>
var $menu = $("#menu");
$menu.on("click", "a", function(e) {
    $menu.find("a").removeClass("selected");
    $(e.target).addClass("selected"); // adds the class on clicked <a>
});
</script>

And it works pretty well until required elements do not contain nested tree. In that cases event.target starts to be the element where an event was actually happened. jQuery solves this problem by changing this to always match event selector:

$menu.on("click", "a", function(e) {
    $menu.find("a").removeClass("selected");
    console.log(e.target.tagName); // => could be <i>, <img> etc.
    $(this).addClass("selected"); // adds the class on clicked <a>
});

Despite it works the solution is not perfect, because in regular event handlers this always matches element that calls the on method. Changing such behavior for delegated events is confusing. While looking for alternative solutions I've found definition of the currentTarget property in W3C:

Used to indicate the EventTarget whose EventListeners are currently being processed. This is particularly useful during capturing and bubbling.

So why not to make it useful for events with selector? It feels very natural and does not conflict with the spec:

DOM.find("#menu").on("click", "a", ["target", "currentTarget"], function(target, currentTarget) {
    this.findAll("a").removeClass("selected");
    currentTarget.addClass("selected"); // adds the class on clicked <a>
});
Clone this wiki locally