【问题标题】:Hammer.js can't remove event listenerHammer.js 无法删除事件监听器
【发布时间】:2013-06-28 14:33:46
【问题描述】:

我像这样创建了一个锤子实例:

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

然后我可以添加一个监听器:

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

但是我无法删除此侦听器,因为以下内容不执行任何操作:

hammertime.off("touch");

我做错了什么?我如何摆脱锤子听众?目前,hammer.js 文档非常糟糕,因此除了存在 .on().off() 方法之外,它没有任何解释。我不能使用 jQuery 版本,因为这是一个性能关键的应用程序。

JSFiddle 展示这个:http://jsfiddle.net/LSrgh/1/

【问题讨论】:

  • 我认为这应该可行...出于好奇,您是否尝试过重新创建实例?喜欢Hammer(el).off("touch")
  • @NicoSantangelo 是的,它什么也没做。听众还在。
  • @NicoSantangelo 还添加了一个显示行为的小提琴,并且可以轻松地对其进行测试。

标签: javascript hammer.js


【解决方案1】:

好的,我想通了。源码很简单,就是这样做的:

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
}

这里要注意的事情(除了一个糟糕的文档)e 它是on 事件中的回调函数,所以你正在做:

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

但是,在删除中,你没有传递回调,所以你这样做:

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

所以,浏览器不知道你是否试图解除绑定,你可以不使用匿名函数来解决这个问题,就像我在:

Fiddle

欲了解更多信息:Javascript removeEventListener not working

【讨论】:

  • 谢谢,我想这是有道理的,我忘记了 removeEventListener() 没有它会失败。如果hammer.js 能添加一些魔法来实现这一点,比如将匿名函数的引用存储在数组或其他东西中,那就太好了。我会向他们建议。
  • 是的,他们可能会解决这个问题以使其对用户不可见,但至少在文档中提及会很好
  • 重要提示:调用 OFF 时,您必须使用与调用 ON 设置/启用事件相同的 Hammer 实例。
【解决方案2】:

要解除与 OFF 的事件绑定,您必须:

1) 将调用 ON 时设置的相同回调函数作为参数传递给 OFF

2) 使用与设置 ON 事件相同的 Hammer 实例

示例:

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

解除绑定事件:

mc.off(eventString, functionEvent);

【讨论】:

  • 如果off 出现在代码的其他部分,您是否希望存储对 Hammer 实例的引用(即mc)?
【解决方案3】:

HammerJS 2.0 现在支持取消​​绑定事件的所有处理程序:

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

【讨论】:

    【解决方案4】:

    这是CodePen exampleNico posted。我为“点击”事件创建了一个简单的包装器(尽管它可以很容易地适应其他任何东西),以跟踪每个 Hammer Manager。我还创建了一个 kill 函数来轻松地停止收听: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 );
    };
    

    所以你基本上会做这样的事情:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-05-23
      • 1970-01-01
      • 1970-01-01
      • 2019-12-18
      • 1970-01-01
      相关资源
      最近更新 更多