简体   繁体   中英

javascript jquery callback accumulates

Issue: Each time div.a is clicked, the number of callbacks when div.b is clicked,accumulates by 1.

var $=jQuery;
$(function(){
   $("div.a").click(function(){cbf(trgmsg);});
});
function trgmsg(){
   alert($.now());
}
function cbf(cb){
   $("div.b").click(function(){cb()});
}

Result:
click div.a once and click div.b => alert() pops-up;
if i click div.a again and click div.b => alert() pops-up twice consecutively;
if i click div.a another time and click div.b => alert() pops-up three times consecutively;
..and so on

I have No idea what the cause of the problem is or if its simply my misunderstanding/misuse of callback functions in JS. Any insights and/or advice will be greatly appreciated. thanks

Quickest fix for your code without a refactor is to just unbind and re-bind.

var $=jQuery;
$(function(){
   $("div.a").click(function(){cbf(trgmsg);});
});
function trgmsg(){
   alert($.now());
}
function cbf(cb){
   $("div.b").off('click').click(function(){cb()});
}

What you have now (refactored) looks like:

(function($){
  $(function(){
    function trgmsg(){
      alert($.now());
    }
    $('div.a').click(function(){
      // every time `div.a` is clicked a new click event is
      // attached to `div.b`.
      $('div.b').click(function(){ // maybe use `.one()` instead of `.click()`?
        cb();
      });
    });
  });
})(jQuery);

You may want to use .one() so after it binds it's only executed once. Or else you need to elaborate on what the actual goal is and see if that can be solves differently.

If you just want to call the supplied function against div.b , when div.a is clicked, this might work for you

var $=jQuery;
$(function(){
   $("div.a").click(function(){cbf(trgmsg);});
});
function trgmsg(){
   alert($.now());
}
function cbf(cb){
   $("div.b")[0].apply(cb);
}

You are attaching multiple click events onto div.b. So every time you click on div.a it is attaching another click event onto div.b so when div.b is clicked each of it's click events are fired. You can try setting a flag that says a click has already been registered.

var $=jQuery;
var flag = 0;
$(function(){
   $("div.a").click(function(){cbf(trgmsg);});
});
function trgmsg(){
   alert($.now());
}
function cbf(cb){
   if (!flag) {
       flag = 1;
       $("div.b").click(function(){cb()});
   }
}

Although I'm not quite sure what your using this for so that may not be your desired functionality.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM