.off无法使用回调

时间:2013-11-03 18:47:09

标签: javascript jquery

我制作了一个小测试代码,因为我不确定是否可以在调用它们的范围之外关闭监听器,我想知道为什么在我的测试代码中,当我在.off方法中包含回调时,代码似乎不再起作用。

var testobj = {
    init: function() {
        testobj.listener();
    },

    listener: function() {

        $(document).on('mousedown', function() {
            testobj.listener_off();
                console.log("on");
        });


    },

    listener_off: function() {
        $(document).on('mouseup', function() {
            $(document).off('mousedown', function() {
                console.log("off");
            });
        });
    }
}

$(function() {
    testobj.init();
});

jsfiddle

再一次,问题在于:

$(document).off('mousedown', function() {
    console.log("off");
});

似乎打破了代码,同时使用:

$(document).off('mousedown');

似乎工作正常。

此外,在处理多个事件监听器(特别是那些对同一事件作出反应的事件)时,什么是打开和关闭它们的最佳做法?我是否正确将它们分成单独的函数,以便稍后调用它们或者可能导致问题?

2 个答案:

答案 0 :(得分:1)

将函数传递给.off()时,表示您要删除该特定处理程序。由于您传递的是新实例化的匿名函数,因此它不是 任何事件的处理程序,因此没有净效果。

当你有一个你有一个引用的处理函数时,.off()的形式是有意义的:变量名,或某个对象的属性名等。这样你可以使用在设置事件处理程序时通过该引用运行,然后在您想要取消设置它时再次:

function someHandler(ev) {
  // handle handle handle ...
}

// ...

$('#foo').on('click', someHandler);

// ...

if (itsChristmasTime()) {
  $('#foo').off('click', someHandler);
}

在您的情况下,您可能只需要一个参数版本,只传递事件名称。跟踪事件处理程序的另一种方法是在事件名称上使用限定符。 JQuery寻找“。”在事件名称中,忽略“。”以及用于事件处理的任何后缀,但它并没有完全忘记。因此,您可以使用它来识别处理程序,而无需跟踪正在使用的特定函数:

$('#foo').on('click.remove-me', function(ev) { ... });

// ...

if (itsChristmasTime()) {
  $('#foo').off('click.remove-me');
}

通过这种方式,您可以为窗口小部件行为的不同方面维护单独的“单击”处理程序,并有选择地只删除其中的一个/部分。

答案 1 :(得分:1)

这是因为当将函数作为第二个参数传递给off函数时,它应该是已注册的相同函数实例

基本上,以下将正在运作:

$(myDiv).on('click', function () {});
$(myDiv).off('click', function () {});

但这会:

function clickHandler() {}

$(myDiv).on('click', clickHandler);
$(myDiv).off('click', clickHandler);

当您在没有第二个参数的情况下调用off时,会删除该特定事件的所有侦听器,这就是为什么它适用于您的情况。