2

I create a hammer instance like so:

var el = document.getElementById("el");
var hammertime = Hammer(el);

I can then add a listener:

hammertime.on("touch", function(e) {
    console.log(e.gesture);
}

However I can't remove this listener because the following does nothing:

hammertime.off("touch");

What am I doing wrong? How do I get rid of a hammer listener? The hammer.js docs are pretty poor at the moment so it explains nothing beyond the fact that .on() and .off() methods exist. I can't use the jQuery version as this is a performance critical application.

JSFiddle to showcase this: http://jsfiddle.net/LSrgh/1/

George Reith
  • 13,132
  • 18
  • 79
  • 148

4 Answers4

6

Ok, I figured it out. The source it's simple enough, it's doing:

on: function(t, e) {
    for (var n = t.split(" "), i = 0; n.length > i; i++)
        this.element.addEventListener(n[i], e, !1);
    return this
},off: function(t, e) {
    for (var n = t.split(" "), i = 0; n.length > i; i++)
        this.element.removeEventListener(n[i], e, !1);
    return this
}

The thing to note here (apart from a bad documentation) it's that e it's the callback function in the on event, so you're doing:

this.element.addEventListener("touch", function() {
    //your function
}, !1);

But, in the remove, you don't pass a callback so you do:

this.element.removeEventListener("touch", undefined, !1);

So, the browser doesn't know witch function are you trying to unbind, you can fix this not using anonymous functions, like I did in:

Fiddle

For more info: Javascript removeEventListener not working

Community
  • 1
  • 1
nicosantangelo
  • 13,216
  • 3
  • 33
  • 47
  • Thanks, I guess that makes sense I forgot that `removeEventListener()` fails without it. It would be nice if hammer.js would add some wizardry to allow this such as storing references to anonymous functions in an array or something. I'll suggest that to them. – George Reith Jun 28 '13 at 15:17
  • Yes, they could probably work around this to make it invisible to the user, but at least a mention in the docs would be nice – nicosantangelo Jun 28 '13 at 15:23
  • 1
    Important: When calling OFF you MUST use the same Hammer instance you used to set/enable the event by calling ON. – engine9pw Jun 08 '15 at 10:21
1

In order to unbind the events with OFF, you must:

1) Pass as argument to OFF the same callback function set when called ON

2) Use the same Hammer instance used to set the ON events

EXAMPLE:

var mc = new Hammer.Manager(element);
mc.add(new Hammer.Pan({ threshold: 0, pointers: 0 }));
mc.add(new Hammer.Tap());
var functionEvent = function(ev) {
    ev.preventDefault();
    // .. do something here
    return false;
};
var eventString = 'panstart tap';
mc.on(eventString, functionEvent);

UNBIND EVENT:

mc.off(eventString, functionEvent);
engine9pw
  • 364
  • 1
  • 5
  • Are you expected to store the reference to Hammer instance (i.e. `mc`) if `off` happens in some other part of the code ? – user Nov 12 '15 at 17:07
0

HammerJS 2.0 does now support unbinding all handlers for an event:

function(events, handler) {
    var handlers = this.handlers;
    each(splitStr(events), function(event) {
        if (!handler) {
            delete handlers[event];
        } else {
            handlers[event].splice(inArray(handlers[event], handler), 1);
        }
    });
    return this;
}
Tamlyn
  • 22,122
  • 12
  • 111
  • 127
0

Here's a CodePen example of what Nico posted. I created a simple wrapper for "tap" events (though it could easily be adapted to anything else), to keep track of each Hammer Manager. I also created a kill function to painlessly stop the listening :P

var TapListener = function(callbk, el, name) {
    // Ensure that "new" keyword is Used
    if( !(this instanceof TapListener) ) {
        return new TapListener(callbk, el, name);
    }
    this.callback = callbk;
    this.elem = el;
    this.name = name;
    this.manager = new Hammer( el );
    this.manager.on("tap", function(ev) {
            callbk(ev, name);
    });
}; // TapListener
TapListener.prototype.kill = function () {
    this.manager.off( "tap", this.callback );
};

So you'd basically do something like this:

var myEl = document.getElementById("foo"),
    myListener = new TapListener(function() { do stuff }, myEl, "fooName");
    // And to Kill
    myListener.kill();
Community
  • 1
  • 1
savgrace
  • 41
  • 3