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/

3
  • I think that should work...out of curiosity, have you tried recreating the instance? like Hammer(el).off("touch") Commented Jun 28, 2013 at 14:40
  • @NicoSantangelo Yep, it does nothing. The listener is still there. Commented Jun 28, 2013 at 14:41
  • @NicoSantangelo also added a fiddle which shows the behaviour, and can easily test that out. Commented Jun 28, 2013 at 14:47

4 Answers 4

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

3
  • 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. Commented Jun 28, 2013 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 Commented Jun 28, 2013 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
    Commented Jun 8, 2015 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);
1
  • Are you expected to store the reference to Hammer instance (i.e. mc) if off happens in some other part of the code ?
    – user
    Commented Nov 12, 2015 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;
}
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();

Not the answer you're looking for? Browse other questions tagged or ask your own question.