开发者

Disable jQuery function after one click, to prevent multiple executions

I have the following function which fetches more comments beyond the 20 that are shown by default:

$('.more_comments_link').live('click', function() {
    $(".more_comments_link").text("Fetching More Comments...");

    var ajaxOpts = {
        type: "get",
        url: "ajax_getcomments.php",
        dataType: 'json',
        data: "&itemid=<? echo $id; ?>&type=1&owner=<? echo $event["data"]["e_creator"]; ?>&more=1",
        success: function(data) {
            $('.discussion-more').after(data);
            $(".discussion-more").hide();
        }
    };

    $.ajax(ajaxOpts);
    return false;
});

It works, but the only problem is, the user can click the button three times really quickly, and it will send three requests to ajax_getcomments.php, getting the same result set every time.

I tried adding

$(".more_comments_link").unbind('click');

but it doesn't do anything.

The initial result set is also fetched with jQuery, hen开发者_开发知识库ce I’m using .live(click'.

I am not sure if it has anything to do with why it’s not working.


live doesn't work with unbind -- you need die instead.

However there is a better solution. Since you probably want to be able to update the content more than once, you can set a variable to see whether a request is currently running:

var requestRunning = false;
$('.more_comments_link').live('click', function () {
    if (requestRunning) { // don't do anything if an AJAX request is pending
        return;
    }

    $(".more_comments_link").text("Fetching More Comments ...");

    var ajaxOpts = {
        type: "get",
        url: "ajax_getcomments.php",
        dataType: 'json',
        data: "&itemid=<? echo $id; ?>&type=1&owner=<? echo $event["
        data "]["
        e_creator "]; ?>&more=1",
        success: function (data) {
            $('.discussion-more').after(data);
            $(".discussion-more").hide();
        },
        complete: function() {
            requestRunning = false;
        }

    };

    requestRunning = true;
    $.ajax(ajaxOpts);
    return false;
});


All of these solutions are far too complex for a very simple solution; use .one():

Simply change live to one. See below:

$('.more_comments_link').one('click', function() {


You can use .die() to unbind .live() events.

  • live
  • die

Or set a flag elsewhere that says the request is in progress and check that at the beginning of the click handler.


You can use:

$('element').off()

This will disable any event of your component that you are listening to.


Depending on your use case, you might not have to use live, in which case one would do exactly what you want it to do.


Try using the disabled keyword. This way you don't have to unbind the function; you just disable it from being pressed:

$('.more_comments_link').live('click', function() {
    $(this).attr("disabled", true);
    $(".more_comments_link").text("Fetching More Comments ...");

    var ajaxOpts = {
        type: "get",
        url: "ajax_getcomments.php",
        dataType: 'json',
        data: "&itemid=<? echo $id; ?>&type=1&owner=<? echo $event["data"]["e_creator"]; ?>&more=1",
        success: function(data) {
            $('.discussion-more').after(data);
            $(".discussion-more").hide();
        }
    };

    $.ajax(ajaxOpts);
    return false;
});


My solution, working global on all Ajax requests. If it is the active request, new with the same URL will be aborted. It is working fine.

var activeRequests = [];

$(document).ajaxComplete(function(e, jqxhr, settings) {
    var i = activeRequests.indexOf(settings.url);
    if (i != -1) {
        setTimeout(function(){
            activeRequests.splice(activeRequests.indexOf(settings.url), 1); }, 75);
    }
});

$(document).ajaxSend(function(e, jqxhr, settings) {
    var i = activeRequests.indexOf(settings.url)
    if (i != -1) {
        jqxhr.abort();
        activeRequests.push(settings.url);
    }
});


$('.more_comments_link').live('click', function(e) {

    if($(e.target).data('oneclicked')!='yes') {

        $(this).text("Fetching More Comments ...");

        var ajaxOpts = {
            type: "get",
            url: "ajax_getcomments.php",
            dataType: 'json',
            data: "&itemid=<? echo $id; ?>&type=1&owner=<? echo $event["data"]["e_creator"]; ?>&more=1",
            success: function(data) {
                $('.discussion-more').after(data);
                $(".discussion-more").hide();
            }
        };

        $.ajax(ajaxOpts);
        return false;
    }

    $(e.target).data('oneclicked','yes');

}); 


You Can use for a single click on a button over the webpage

 $('button id or classs').one('click',function(){    
 });


For me this worked:

$('.more_comments_link').live('click', function() {

  if(e.handled !== true) // This will prevent event firing more than one time
  {
    e.handled = true;
    // Your code here...
  }
});
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜