jQuery回调函数累积

jQuery callback function accumulating

本文关键字:函数 回调 jQuery      更新时间:2023-09-26

我为一个自定义确认框编写了一些代码,该框在按下确认按钮(yes按钮)时调用一个函数,并将另一个函数作为参数传递,然后将其绑定到两个不同的按钮点击,并将不同的函数作为参数。例如:

$('#button1').click(function() {
    callFunction(function() { alert("test"); });
});
$('#button2').click(function() {
    callFunction(function() { alert("test2"); });
});
function callFunction(callback) {
    //code to display custom confirm box
    console.log(callback);
    $('.confirm-box .yes-button').click(function() {
        callback();
    });
}

一切都如预期的那样发生,确认框出现,点击确认按钮,我会执行一个回调函数,它会提醒"test"(或"test2",具体取决于哪个按钮调用了确认框)。当我单击发送警报"测试"的函数的按钮1,然后不是确认我取消了它(没有按预期发生任何事情),然后单击将警报("测试2")作为回调函数传递的按钮2时,问题就出现了。现在,一旦我按下yes按钮而不是只提醒"test2",我就会同时收到"test2"answers"test"警报,尽管我写的console.log只记录了在点击按钮2时提醒"test1"的功能。这些回调函数似乎堆积在某个地方,但我不明白在哪里以及为什么。

.click()函数可以为一个元素添加多个处理程序,我认为这就是这里的情况。试试这个:

// ...
$('.confirm-box .yes-button').unbind('click').click(function() {
    callback();
});

这将在应用新的单击处理程序之前删除以前的任何单击处理程序。

执行代码时:

$('.confirm-box .yes-button').click(function() {
    callback();
});

您正在将事件处理程序绑定到.yes-button元素。如果你运行该代码两次,它将绑定两个事件。依此类推。

一种解决方案是使用.one,这样事件处理程序将在第一次触发后被删除:

$('.confirm-box .yes-button').one("click", function() {
    callback();
});

如果同时打开两个确认框或有两个.yes-button元素,这当然会有问题,但对于一个简单的用例来说,它工作得很好。

发生的情况是,每次单击按钮时,callFunction方法都在执行。它运行该代码块,并将事件侦听器应用于$(".confirm-box.yes button")按钮。因此,点击你的按钮N次也会应用点击监听器N次。一种解决方案是将函数存储在变量中。

不确定最终目标是什么,但这是一个解决方案。另一种解决方案是每次删除按钮事件侦听器。

var functionToCallOnYes = function() {};
$('#button1').click(function() {
  functionToCallOnYes = function() {
    alert("test");
  };
});
$('#button2').click(function() {
  functionToCallOnYes = function() {
    alert("test2");
  };
});

$('.confirm-box .yes-button').click(function() {
  console.log(functionToCallOnYes);
  functionToCallOnYes();
});

您可以通过按类设置标识来实现,

var button = $('.confirm-box .yes-button');
$('#button1').click(function() {
  button.removeClass("b").addClass("a");
});
$('#button2').click(function() {
  button.removeClass("a").addClass("b");
});
button.click(function() {
  if($(this).hasClass("a")){
     callBackForButton1();
  } else {
     callBackForButton2();
  }
});

为单个元素堆叠事件处理程序是一种糟糕的做法。

是的,额外的回调正在堆积。在$('button1').click(f)中,每次单击button1时,都会调用函数f,不带任何参数。在这种情况下,f就是callFunction——每次调用.confirm-box .yes-button元素时,该函数本身都会为其附加一个新的处理程序。因此,在第N次点击时,您应该会收到N-1个警报。

为了简化这类操作,您可以在JavaScript中按名称引用函数。因此,如果你有function test() { console.log("test"); };,你可以只写一次$(".confirm-box").click(test),从那时起,每次点击.confirm-box都会将test打印到控制台。

通常,如果回调的唯一目的是调用回调,则可以删除该回调。