【问题标题】:How to check if an event is bound to an element, to prevent duplicate bindings?如何检查事件是否绑定到元素,以防止重复绑定?
【发布时间】:2013-07-28 12:46:26
【问题描述】:

我有一个函数,它基本上创建了一个覆盖整个页面的覆盖 div 元素。它还将调整大小事件绑定到窗口,因此每当调整窗口大小时,叠加层也会改变其大小:

function stdOverlay() {
    var overlay = $('<div />').css({width : $(window).width(), height : $(window).height()});
    var overlayResize =
    function() {
        $(overlay).css({width : $(window).width(), height : $(window).height()});
    };
    $('body').append(overlay);
    $(window).resize(overlayResize);
    //... other codes,  like remove overlay and unbind the events
    //$('div.stdgui-overlay').unbind('resize', overlayResize);
}

每次调用该函数时,它都会添加一个覆盖(如果没有),并将调整大小事件绑定到窗口。当它应该删除覆盖事件时,它还会取消绑定事件。 如何检查 overlayResize 方法是否绑定到窗口元素,以防止重复绑定?类似:

    if(overlyResize is not bound to window)
        $(window).resize(overlayResize);
    else
        //do something else or do nothing;

【问题讨论】:

  • 这个页面有答案。 [jquery 检查事件是否存在][1] [1]: stackoverflow.com/questions/1515069/…
  • @emaniacs 我已经看过这些答案了,不幸的是 $.data 不是一个可以长期依赖的东西,因为它很容易被 jQuery 经常改变。见this

标签: jquery events bind


【解决方案1】:

您可以使用标志,但最简单的方法是取消绑定然后重新绑定事件以确保它只绑定一次:

$(window).off('resize', overlayResize).on('resize', overlayResize);

【讨论】:

  • $(window).off('resize', overlayResize).on('resize', overlayResize); 是一个漂亮的小技巧。但是我怎样才能使用标志呢?你能解释一下吗?
  • 我明白了,但这需要分配一个全局变量。您是否认为创建这样的全局标志是个好主意,只是为了检查之前是否做过某些事情?我相信会有更多的案例需要检查。这意味着使用更多的标志。创建依赖全局标志来操作的函数是一种好习惯吗?
  • 这是一个示例,您可以随意分配标志,例如使用 jQuery 的 data() 方法,实际上不需要全局变量,但它在这样的小示例中更好地说明了功能.
【解决方案2】:

最简单的方法是首先取消绑定,然后将事件处理程序绑定到此元素,如已接受的答案中所述。

演示

(function($) {
  $.fn.hasThisEventHandler = function(_event) { // convention:  event.namespace

    var elemEvents = $._data(this[0], 'events');

    if (elemEvents) {

      var ns = void 0;
      var evtName = _event;

      if (_event.indexOf(".")) {
        var eva = _event.split(".");
        evtName = eva[0];
        ns = eva[1];
      }

      var mm = elemEvents[evtName];

      if (mm && mm.length > 0) {

        if (ns === void 0) {
          return true;
        }

        if (ns) {
          for (var i = 0; i < mm.length; i++) {
            if (mm[i].namespace && mm[i].namespace === ns) {
              return true;
            }
          }
        }
      }
    }
    return false;
  }
}(jQuery));

$(document).on("mousemove.isMouseOverMe", function(e) {});
$("body").click(function() {});

console.log("mousemove.isMouseOverMe eventhandler bound to document: --> " + $(document).hasThisEventHandler("mousemove.isMouseOverMe"));

console.log("click eventhandler bound to body: --> " + $("body").hasThisEventHandler("click"));
&lt;script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"&gt;&lt;/script&gt;

如果你真的想检查,你可以使用这个插件:

(function ($) {
$.fn.hasThisEventHandler = function (_event) {  // convention:  event.namespace

var elemEvents = $._data(this[0], 'events');

if (elemEvents) {

    var ns = void 0;
    var evtName = _event;

    if (_event.indexOf(".")) {
        var eva = _event.split(".");
        evtName = eva[0];
        ns = eva[1];
    }

    var mm = elemEvents[evtName];

    if (mm && mm.length > 0) {

        if (ns === void 0) {
            return true;
        }

        if (ns) {
            for (var i = 0; i < mm.length; i++) {
                if (mm[i].namespace && mm[i].namespace === ns) {
                    return true;
                }
            }
        }
    }
}
return false;
}
} (jQuery));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-15
    • 2014-04-07
    相关资源
    最近更新 更多