如何停止jQuery回调函数?

3

我有两个HTML元素:A和B,以下是jQuery代码:

$('A').click(function(){
    $('B').click(function(){
        console.log("hello");
    })
})

当我点击A然后点击B时,它会显示"hello",这很好。
但是当我再次点击A然后点击B时,它会显示两个"hello",这是不希望看到的。我只想要一个"hello"。
我差不多知道原因了,可能是回调函数的结果:在第一次点击后,B仍在等待用户点击。
现在我的问题是:如果我仍想要将"点击B"放在"点击A"内部("点击B"是"点击A"的回调函数),我该如何解决双重结果问题?
我对回调函数还不熟悉,请帮忙!!!
3个回答

4

您当前的代码并没有完全做到您想要的效果。每次点击 A,它都会向 B 添加一个新的点击处理程序。因此,如果您点击 A 3 次,则在 B 上有 3 个点击处理程序,所有这些处理程序都会在单击 B 时执行。

一种解决方法是在 A 的点击处理程序中注销 B 的点击处理程序,例如:

$('A').click(function(){
    // Ensure we only ever have one click-handler on B
    // by clearing existing handlers before adding our
    // new one.
    $('B').unbind('click').click(function(){
        console.log("hello");
    })
})

然而,这段代码的副作用是删除所有B的处理程序,可能不是您想要的。更健壮的版本是创建一个命名处理程序,而不是匿名处理程序,并添加和删除它来仅删除特定处理程序。这样可以针对您想要的特定处理程序进行操作。您还可以使用命名空间实现此目的(请参阅解除绑定文档并查找“命名空间”)。
var helloHandlerForB = function() { console.log("hello"); };

$('A').click(function(){
    // Ensure we only ever have one click-handler on B
    // by clearing existing handlers before adding our
    // new one.
    $('B').unbind('click', helloHandlerForB).click(helloHandlerForB);
})

工作但丑陋的解决方案。说真的,你不想每次单击时都取消和重新绑定事件处理程序吧? - Christoph
@Christoph 我能想到的另一种解决方案是使用全局变量,这甚至更不美观!编辑我刚刚注意到Bondye也提供了这种方法 :) - RB.
确定?看看我的回答吧 ;) - Christoph
谢谢您的答复,似乎有一种更简单的方法来解决这个问题(方案3),他的解决方案是否存在任何缺陷? - webberpuma

1

你也可以创建一个布尔值来检查是否点击了a。

例如:fiddle

var aIsClicked = false; //boolean

$('#A').click(function(){
   $('#log').html('clicked on A');
   aIsClicked = true;
});

$('#B').click(function(){
   if(aIsClicked) //check if a was clicked
   {
       $('#log').html('clicked on B and A was clicked');
       alert("hello");
   }
    else
    {
        $('#log').html('clicked on B and A was not clicked');
    }
});​


1
问题在于,每次连续点击 A 都会向您的 B 添加另一个点击处理程序。当您单击 B 时,这些处理程序中的每一个都会被执行。因此,如果您点击 A 十次,则已将十个点击处理程序绑定到 B :-D

为避免其他解决方案的问题,如常量解除和重新绑定以及全局变量,这两者都很讨厌,请改用此干净的解决方案:

$('A').one("click", function(){
    $('B').click(function(){
        console.log("hello");
    })
})

通过使用.one()而不是click,可以仅触发A上的单击事件,并将一个单击事件处理程序绑定到您的元素B

示例Fiddle


非常感谢,这个解决方案似乎比其他方案简单得多,但是这个解决方案有什么缺陷吗? - webberpuma
@Webberpuma,重新阅读您的陈述后,我有以下问题:用户在单击A一次后,是否只能单击B一次?还是允许他在单击A后随意单击B? - Christoph

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接