Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Event delegation with Hammer.js

How would I do jQuery-style event delegation with plain JavaScript in Hammer.js? E.g.:

Hammer(document).on('tap', '.item', function () {
  console.log('tapped')
})

Is this directly possible or do I have to do the delegation myself?

like image 638
Sacha Avatar asked Jul 26 '13 11:07

Sacha


1 Answers

Inspired by Jools' answer, here is what I've come up with. I didn't bother with a pure-JS solution--in fact, this is intended for use with a Backbone.View, but is easily adaptable to other situations.

It will stop climbing the node tree when it reaches the View's root element (this.el). Starting from the target identified by the HammerJS event, it will seek the first element matching the specified selector, and return undefined if no such element is found.

To use in a non-Backbone environment, just pass in a reference to the limiting/containing element as a 3rd argument (as in Jools' solution) and use it to replace this.el.

/**
 * @param {Node}target - the target of the received event
 * @param {String}selector - any jQuery-compatible selector
 */
getEventDelegate: function (target, selector) {
     var delegate;
     while (target && target != this.el) {
        delegate = $(target).filter(selector)[0];
        if (delegate) {
           return delegate;
        }
        target = target.parentNode;
     }
     return undefined;
  }

If you have an onTap callback function, it might look something like this:

/**
 * @param {Event}ev
 */
onTap: function (ev) {
   var target = this.getEventDelegate(ev.target, "#desiredTarget");
   if (target) {
      // TODO something with the target...
   }
}

And to hook it all up, you'd want something like this...

this._hammer = new Hammer(this.el);
this._hammer.on('tap', _.bind(this.onTap, this));

(and don't forget to call this._hammer.destroy() when your view is destroyed!)

like image 150
Lambart Avatar answered Sep 20 '22 04:09

Lambart