George Reith
George Reith

Reputation: 13476

Hammer.js can't remove event listener

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/

Upvotes: 2

Views: 7467

Answers (4)

engine9pw
engine9pw

Reputation: 364

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);

Upvotes: 1

savgrace
savgrace

Reputation: 41

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();

Upvotes: 0

Tamlyn
Tamlyn

Reputation: 23564

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;
}

Upvotes: 0

nicosantangelo
nicosantangelo

Reputation: 13716

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

Upvotes: 6

Related Questions