如何检查单击事件是否已经绑定-JQuery

我正在用一个按钮绑定一个单击事件:

$('#myButton').bind('click',  onButtonClicked);

在一个场景中,这会被多次调用,所以当我执行 trigger时,我会看到多个 ajax 调用,我想阻止它们。

如果 bind之前没有被绑定,我怎么做。

144931 次浏览

如果使用 jQuery 1.7 + :

你可以在 on之前拨打 off:

$('#myButton').off('click', onButtonClicked) // remove handler
.on('click', onButtonClicked); // add handler

否则:

你可以先解除绑定:

$('#myButton').unbind('click', onButtonClicked) //remove handler
.bind('click', onButtonClicked);  //add handler

更新24 Aug’12 : 在 jQuery 1.8中,不再可以使用 .data('events')访问元素的事件。(详情请参阅 这个窃听器。)可以使用内部数据结构 jQuery._data(elem, 'events')访问相同的数据,这种结构没有文档记录,因此不能100% 保证保持稳定。然而,这应该不会成为一个问题,上面插件代码的相关行可以修改如下:

var data = jQuery._data(this[0], 'events')[type];

JQuery 事件存储在一个名为 events的数据对象中,因此您可以在以下内容中进行搜索:

var button = $('#myButton');
if (-1 !== $.inArray(onButtonClicked, button.data('events').click)) {
button.click(onButtonClicked);
}

当然,如果您能够对应用程序进行结构化设计,使这段代码只被调用一次,那将是最好的。


这可以封装到一个插件中:

$.fn.isBound = function(type, fn) {
var data = this.data('events')[type];


if (data === undefined || data.length === 0) {
return false;
}


return (-1 !== $.inArray(fn, data));
};

然后你可以打电话:

var button = $('#myButton');
if (!button.isBound('click', onButtonClicked)) {
button.click(onButtonClicked);
}

还有一种方法——用 CSS 类和过滤器标记这样的按钮:

$('#myButton:not(.bound)').addClass('bound').bind('click',  onButtonClicked);

在最近的 jQuery 版本中,用 on取代了 bind:

$('#myButton:not(.bound)').addClass('bound').on('click',  onButtonClicked);

我认为,最好的方法是使用 live ()或 Committee ()在父元素中捕获事件,而不是在每个子元素中捕获事件。

如果您的按钮位于 # father 元素中,您可以替换:

$('#myButton').bind('click', onButtonClicked);

作者

$('#parent').delegate('#myButton', 'click', onButtonClicked);

即使在执行这段代码时 # myButton 还不存在。

我的版本是这样的:

Utils.eventBoundToFunction = function (element, eventType, fCallback) {
if (!element || !element.data('events') || !element.data('events')[eventType] || !fCallback) {
return false;
}


for (runner in element.data('events')[eventType]) {
if (element.data('events')[eventType][runner].handler == fCallback) {
return true;
}


}


return false;
};

用法:

Utils.eventBoundToFunction(okButton, 'click', handleOkButtonFunction)
if ($("#btn").data('events') != undefined && $("#btn").data('events').click != undefined) {
//do nothing as the click event is already there
} else {
$("#btn").click(function (e) {
alert('test');
});
}

我写了一个非常小的插件,叫做“ once”,它可以做到这一点。

$.fn.once = function(a, b) {
return this.each(function() {
$(this).off(a).on(a,b);
});
};

简而言之:

$(element).once('click', function(){
});

JQuery 有 解决方案:

$( "#foo" ).one( "click", function() {
alert( "This will be displayed only once." );
});

相等于:

$( "#foo" ).on( "click", function( event ) {
alert( "This will be displayed only once." );
$( this ).off( event );
});

基于@konrad-garus 回答,但使用 data,因为我认为 class应该主要用于造型。

if (!el.data("bound")) {
el.data("bound", true);
el.on("event", function(e) { ... });
}

为什么不用这个

unbind()bind()之前

$('#myButton').unbind().bind('click',  onButtonClicked);

为了避免检查/绑定/取消绑定,您可以更改您的方法! 为什么不使用 Jquery. on () ?

由于不推荐使用 Jquery 1.7,. live () ,. committee () ,现在您可以使用. on ()来

为所有匹配当前选择器 现在和将来的元素附加一个事件处理程序

这意味着您可以将事件附加到仍然存在的父元素,并附加子元素,无论它们是否存在!

像这样使用. on () :

$('#Parent').on('click', '#myButton'  onButtonClicked);

你捕获事件点击父母,它搜索子’# myButton’如果存在..。

因此,在删除或添加子元素时,不必担心是添加还是删除事件绑定。

试试:

if (typeof($("#myButton").click) != "function")
{
$("#myButton").click(onButtonClicked);
}

截至2019年6月,我已经更新了这个函数(它正在满足我的需要)

$.fn.isBound = function (type) {
var data = $._data($(this)[0], 'events');


if (data[type] === undefined || data.length === 0) {
return false;
}
return true;
};