jQuery在元素上保留所有事件侦听器以供将来设置

时间:2017-09-14 12:25:29

标签: javascript jquery jquery-events

使用jQuery我需要:

  1. 保留添加到元素
  2. 的所有事件处理程序的列表
  3. 将它们全部移除几秒钟
  4. 将事物返回到初始状态(重新分配相同的事件处理程序)
  5. 我发现获取当前侦听器的列表(一些jQuery内部机制):

    var eventsSubmitBtn = $._data(submitButton[0], "events");
    

    然后我可以用

    删除所有事件监听器
     submitButton.off();
    

    但最后的话似乎没有起作用

     setTimeout(function () {
          $._data(submitButton[0], "events", eventsSubmitBtn);
        }, 5000);
    

    eventsSubmitBtn是一个空数组。

    这是应该通过初始设置完成的方式,我需要对这些对象进行深度克隆,或者这可以通过$._data完成吗?

    N.B。我有可能在所有其他系统js代码之后添加我的cistom代码,因此我无法将代码分配给$.fn.on。我编写的代码将在启动时运行最后一个代码,并在我的脚本运行之前附加其他事件侦听器。

1 个答案:

答案 0 :(得分:2)

当您获得$._data()返回的对象的引用时,对该对象的任何更改都不会被忽视,即在您调用.off()之后,该对象将发生更改以反映该对象没有再加上处理程序。

您可以通过拍摄对象的浅表副本来解决此问题(例如,使用Object.assign)。

但这并不是一种推荐的推荐方式。根据{{​​3}}," jQuery._data(element, "events") ...是一个未记录的内部数据结构,不应修改。" 。当您在恢复处理程序时修改它时,这不是最佳实践。但即使只读它也只能用于调试,而不是生产代码。

在事件处理代码中添加条件会更为谨慎:

var ignoreEventsFor = $(); // empty list

$("#button").on('click', function () {
    if (ignoreEventsFor.is(this)) return;
    // ...
});

然后,在需要时,将ignoreEventsFor设置为您要忽略事件的元素。如果您想恢复正常,请再次将其设置为$()

现在将此添加到所有事件处理程序可能会成为负担。如果您坚持使用on()来附加事件处理程序,那么您可以扩展$.fn.on,以便将此逻辑添加到您传递给它的处理程序。

以下演示有一个按钮,可通过更改背景颜色来响应单击。使用复选框,您可以禁用此功能:



/* Place this part immediately after jQuery is loaded, but before any 
   other library is included 
*/
var ignoreEventsFor = $(), // empty list
    originalOn = $.fn.on;
$.fn.on = function (...args) {
    var f = args[args.length-1];
    if (typeof f === 'function') {
        args[args.length-1] = function (...args2) {
            if (ignoreEventsFor.is(this)) return;
            f.call(this, ...args2);
        };
    }
    originalOn.call(this, ...args);
}
/* This next part belongs to the demo, and can be placed anywhere */
$(function () {
    $("#colorButton").on('click', function () {
        // Just some handler that changes the background
        var random = ('00' + (Math.random() * 16*16*16).toString(16)).substr(-3);
        $('body').css({ backgroundColor: "#" + random });
    });

    $("#toggler").on('change', function () {
        // Toggle the further handling of events for the color button:
        ignoreEventsFor = $(this).is(':checked') ? $("#colorButton") : $();
    });
});

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="colorButton">Change color</button><br>
<input type="checkbox" id="toggler">Disable events
&#13;
&#13;
&#13;

注意:上面的代码使用ES6传播/休息语法:如果您需要支持IE,则必须使用arguments变量apply,...等编写。