bind event only once

前端 未结 13 2099
予麋鹿
予麋鹿 2020-12-05 03:45

I have the following code:

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

someMethod is called twice and thus click event is binded

相关标签:
13条回答
  • 2020-12-05 04:04

    You can use this jQuery extension function.

    $.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);
      }
    };
    

    Instead of doing this

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

    Ya do this

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

    Now when I have a function around it

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

    And I call it multiple times

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

    It only does it once.

    Notice that the extension works by checking both uid and type. This means that you can bind different types of handlers with the same uid, you may or may not want this. To change it edit.

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

    With something like

    var dataStr = "handler-"+uid;

    0 讨论(0)
  • 2020-12-05 04:05

    In addition to pna's answer you may wish to think about namespacing your event so you do not go around unbinding all the click events accidentally.

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

    https://api.jquery.com/event.namespace/

    0 讨论(0)
  • 2020-12-05 04:08

    This is a suggestion since I do not know your logic. May or may not work for you.

    Try combining jquery live() and one() functions will give you a better result than event rebinds.

    The special cases work when you have 2 DOM elements (parent & child). Live() at parent node makes sure event will be invoked, and then calls one() to dynamically register event which would be executed only once. (this provides similar functionality like rebinds).

    0 讨论(0)
  • 2020-12-05 04:13

    If you want to bind to the object only once, you should implement a flag and stick to that object.

    For example:

    if($('#id') && $('#id').data('done') == null)) {
        $('#id').bind('click', function() {
            alert('hello');
        });
    
        $('#id').data('done', true);
    }
    
    0 讨论(0)
  • 2020-12-05 04:15

    Or use jQuery's one() function which is similar to on() but only fires the event once, even if you bind it multiple times.

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

    0 讨论(0)
  • 2020-12-05 04:16
    var bound = false;
    
    function someMethod()
    {
        if(!bound)
        {
           $(obj).click(function {});
           bound = true;
        }
    }
    

    but I would probably look into why it;s being called twice before making some kind of workaround.

    0 讨论(0)
提交回复
热议问题