绑定事件只有一次

时间:2011-12-07 00:21:23

标签: jquery

我有以下代码:

function someMethod()
{
  $(obj).click(function {});
}

someMethod被调用两次,因此click事件被绑定两次。我怎样才能让它只绑定一次?

13 个答案:

答案 0 :(得分:178)

如果您可以申请,可能需要查看event.preventDefaultevent.stopPropagation 或者在每次方法中取消绑定和绑定,例如

function someMethod()
{
  $(obj).off('click').on('click', function(e) {
    // put your logic in here 
  });
}

答案 1 :(得分:83)

除了pna的回答,你可能还想考虑命名空间事件,这样你就不会意外地解除所有点击事件的绑定。

function someMethod() {
    $(obj).unbind('click.namespace').bind('click.namespace', function() { });
}

http://docs.jquery.com/Namespaced_Events

答案 2 :(得分:19)

没有内置方法来确定您是否已绑定此特定函数。您可以将多个单击函数绑定到对象。例如:

$('#id').bind('click', function(){
alert('hello');
});


$('#id').bind('click', function(){
alert('goodbuy');
});

如果你在单击对象时执行上述操作,它将提示你,然后再见。要确保只有一个函数绑定到click事件,取消绑定click事件处理程序,然后绑定所需的函数,如下所示:

$(obj).unbind('click').bind('click', function(){... });

答案 3 :(得分:12)

显而易见的解决方案是不要两次调用someMethod()。如果你无法解决这个问题,那么你可以保留一个状态变量,这样它就可以像这样绑定一次:

function someMethod()
{
    if (!someMethod.bound) {
        $(obj).click(function() {});
        someMethod.bound = true;
    }
}

注意:这使用函数本身的属性,而不是引入一个全局变量来跟踪它是否已被绑定。您还可以在对象本身上使用属性。

你可以在这里看到它:http://jsfiddle.net/jfriend00/VHkxu/

答案 4 :(得分:10)

或者使用jQuery的one()函数,它类似于on(),但只触发一次事件,即使你多次绑定它。

http://api.jquery.com/one/

答案 5 :(得分:5)

jQuery只调用一次函数非常简单:

function someMethod()
{

     $(obj).click(function() {});
      this.someMethod = $.noop;
}

答案 6 :(得分:2)

这是一个建议,因为我不知道你的逻辑。可能或可能不适合你。

尝试组合jquery live()和one()函数会比事件重新绑定更好。

当您有2个DOM元素(父级和子级)时,特殊情况会起作用。父节点上的Live()确保将调用事件,然后调用one()来动态注册仅执行一次的事件。 (这提供了类似rebinds的功能)。

答案 7 :(得分:1)

var bound = false;

function someMethod()
{
    if(!bound)
    {
       $(obj).click(function {});
       bound = true;
    }
}

但是我可能会研究一下它为什么;在做出某种解决方法之前被调用两次。

答案 8 :(得分:1)

如果只想绑定一次对象,则应该实现一个标志并坚持该对象。

例如:

if($('#id') && $('#id').data('done') == null)) {
    $('#id').bind('click', function() {
        alert('hello');
    });

    $('#id').data('done', true);
}

答案 9 :(得分:1)

您可以将css类添加到绑定元素,然后将其过滤掉:

function someMethod()
{
    $(obj).not('.click-binded')
          .click(function {})
          .addClass('click-binded');
}

此方法也可用于插件:

  $(obj).not('.datetimepicker-applied')
        .datetimepicker()
        .addClass('datetimepicker-applied');

答案 10 :(得分:1)

您可以使用此jQuery扩展功能。

$.fn.once = function (type, fn, uid) {
  if(uid == undefined) {
    console.error("Called $.once without uid\n", this, "\n", fn);
  }

  var dataStr = type+"-handler-"+uid;
  if(!this.data(dataStr)) {
    this.data(dataStr, true);
    this.on(type, fn);
  }
};

而不是这样做

$("button").on("click", function(){
  alert("You Clicked On A Button");
});

雅做这个

$("button").once("click", function(){
  alert("You Clicked On A Button");
}, "btnHandler");

现在当我有一个功能

function addBtnHandler() {
  $("button").once("click", function() {
    alert("You Clicked On A Button");
  }, "btnHandler");
}

我多次打电话

addBtnHandler();
addBtnHandler();
addBtnHandler();

它只做一次。

请注意,扩展程序通过检查uid和type来工作。这意味着您可以使用相同的uid绑定不同类型的处理程序,您可能想要也可能不想要这样。要改变它,请编辑。

var dataStr = type+"-handler-"+uid;

类似

var dataStr = "handler-"+uid;

答案 11 :(得分:1)

我还尝试使用off和on on jquery方法只对dom元素绑定事件一次,该dom元素尚未存在或者尚未创建dom元素。

$('.select').off('event').on('event', 'selector', function(e){ // });

此代码无法正常运行

我遇到了一个非常有利可图的方法,即“一个人”。方法。当您只想绑定一次事件时,它非常有用。

您可以在http://api.jquery.com/one/

找到该文档

这与' on'但与其行为不同,不要坚持多个选择器的事件。

$('body').one('click', 'selector', function(){ // do your stuff here });

答案 12 :(得分:1)

你可以使用纯粹的JS,使用 addEventListener 方法和他的一次选项来实现这个目标

target.addEventListener('click', handler, {once: true});