Javascript 如何防止.done处理程序被多次调用?

Javascript 如何防止.done处理程序被多次调用?,javascript,jquery,Javascript,Jquery,我有一个JQuery表达式,按下按钮,从服务器获取一些HTML,然后将其附加到文档中的DOM节点: <script type="text/javascript"> $(document).ready(function () { $(".addbutton").click(function () { var addbuttonNode = $(this); $.post("/Inte

我有一个JQuery表达式,按下按钮,从服务器获取一些HTML,然后将其附加到文档中的DOM节点:

<script type="text/javascript">
        $(document).ready(function () {
            $(".addbutton").click(function () {
                var addbuttonNode = $(this);
                $.post("/InteractiveApplications/GetQuizAnswer", { id: '@guid' })
                    .done(function (data) {
                        $(addbuttonNode).next().next().append(data);   //find better way of doing this  
                    });
            });
        });
    </script>

$(文档).ready(函数(){
$(“.addbutton”)。单击(函数(){
var addbuttonNode=$(此项);
$.post(“/InteractiveApplications/GetQuizAnswer”,{id:'@guid'})
.完成(功能(数据){
$(addbuttonNode.next().next().append(data);//找到更好的方法
});
});
});
我的网站上有多个“.addButton”按钮。我遇到的问题是,在多次单击按钮之后,我的.done处理程序被多次调用


我的猜测是,我有一个正在执行的事件处理程序列表,我无法理解在何处/为什么这样做,或者我如何防止它发生。

尝试使用bind和unbind函数进行事件处理。然后,您可以在单击函数执行一次后解除其绑定

<script type="text/javascript">
    $(document).ready(function () {
        $(".addbutton").bind('click',function () {
            var addbuttonNode = $(this);
            $.post("/InteractiveApplications/GetQuizAnswer", { id: '@guid' }).done(function (data) {
                addbuttonNode.next().next().append(data);
            });
            addbuttonNode.unbind('click');
        });
    });
</script>

$(文档).ready(函数(){
$(“.addbutton”).bind('click',函数(){
var addbuttonNode=$(此项);
$.post(“/InteractiveApplications/GetQuizAnswer”,{id:'@guid'}).done(函数(数据){
addbuttonNode.next().next().append(数据);
});
addbuttonNode.unbind('click');
});
});
另一种几乎相同的方法,我认为这应该更好:

<script type="text/javascript">
    $(document).ready(function () {
        $(".addbutton").each(function(){
            $(this).bind('click',function () {
                $.post("/InteractiveApplications/GetQuizAnswer", { id: '@guid' }).done(function (data) {
                    addbuttonNode.next().next().append(data);
                });
                $(this).unbind('click');
            });
        });
    });
</script>

$(文档).ready(函数(){
$(“.addbutton”)。每个(函数(){
$(this).bind('click',函数(){
$.post(“/InteractiveApplications/GetQuizAnswer”,{id:'@guid'}).done(函数(数据){
addbuttonNode.next().next().append(数据);
});
$(this.unbind('click');
});
});
});
我还没试过,但它应该能用,试试看!:)


您还可以设置类或数据属性来检查按钮是否已单击。然后,您可以像if($(this).hasClass('clicked'){return;}或其他什么一样退出脚本。

您可以检查脚本中是否存在任何挂起的请求:

$(document).ready(function () {
     $(".addbutton").click(function () {
         // if any request pending, return {undefined}
         if ($.active) return;
         var addbuttonNode = $(this);
         $.post("/InteractiveApplications/GetQuizAnswer", {
             id: '@guid'
         }).done(function (data) {
             // instead of .next().next()
             $(addbuttonNode).nextAll('selector').first().append(data); //find better way of doing this  
             // or .parent().find('selector')
         });
     });
 });
如果您希望每个按钮只能单击一次,请使用jQuery
.one()
方法:

$(document).ready(function () {
     $(".addbutton").one('click', function () {
         var addbuttonNode = $(this);
         $.post("/InteractiveApplications/GetQuizAnswer", {
             id: '@guid'
         }).done(function (data) {
             // instead of .next().next()
             $(addbuttonNode).nextAll('selector').first().append(data); //find better way of doing this  
             // or .parent().find('selector')
         });
     });
 });

问题不在于你做了什么,请求做了一次又一次,而不是在完成之后调用done。。可以在数据对象中保留状态::

$(document).ready(function () {
    var posting = false;
    $(".addbutton").data("done", false).click(function () {
        var addbuttonNode = $(this);
        if (!addbuttonNode.data("done")) {
            addbuttonNode.data("done", true);
            $.post("/InteractiveApplications/GetQuizAnswer", { id: '@guid' })
                .done(function (data) {
                    $(addbuttonNode).next().next().append(data);   
                });
        }
    });
});

我会这样做:

$(".addbutton").click(function () {
            var addbuttonNode = $(this);
            addbuttonNode.attr('disabled',true);
            $.post("/InteractiveApplications/GetQuizAnswer", { id: '@guid' })
                .done(function (data) {
                    $(addbuttonNode).next().next().append(data);   //find better way of doing this  
                     addbuttonNode.attr('disabled',false);
                });
        });

如果将jquery对象存储在“var addbuttonNode=$(this);”之类的变量中,则在使用该变量访问.done()之后的元素时,不需要使用jquery对其进行包装。问题中没有足够的数据来提供明确的答案。您可以制作一个MCVE吗?您正在将一个事件处理程序附加到一个按钮上,因此只要您单击该按钮,事件处理程序就会被多次调用。由于您提到多次单击按钮,您的事件处理程序必然会被多次调用,从而发出多个ajax请求,从而进行多个已完成的调用。@BalázsVarga这是不可能的,因为diffirent按钮可能给出不同的答案,他将不得不使用按钮保存数据。因此,也许你需要在加载时禁用按钮。但他有多个按钮,一个活动请求下所有按钮都将被禁用。@HaSuKrOnOs Ya但这就是我对这个问题的理解。我可能是错的,我不清楚预期的行为是什么。如果只有一个按钮必须被禁用,那么逻辑是检查任何特定的按钮数据/类/任何东西,并根据itI设置逻辑。我不明白为什么会被否决,它清楚地显示了理论,并且理论是有效的。也许不是最干净的解决方案。。但从防御性角度来说,这并不是一个坏问题。它提供了一个直观的解决方案,而不是一些有助于防止问题发生的东西。据我所知,Disabled元素不会触发click事件,因此这可以防止问题的发生。没错,但在控制台中键入:$(“.addbutton”)。click();它仍然会开火