tags:

views:

281

answers:

4

How can I stop loading function after user is clicked too many times on link?

Jquery code looks like:

$(document).ready(function(){
$(".menu_rfr").click(function() {
$("#main").html('<img src="img/spin.gif" class="spin">');
location.replace($(this).attr('rel'));

});

$(".menu_clickable").click(function() {
$("#main").html('<img src="img/spin.gif" class="spin">');
$("#main").load($(this).attr('rel'));

});

});

HTML:

<div class="menu_rfr prof_info" id="prof_info" rel="?a=1">info</div>
<div class="menu_clickable prof_info3" id="prof_info" rel="?a=3">info 3</div>

EDIT:

this is the link of the sample page with this Jquery code. link text

+3  A: 

Disable the button once it has been clicked:

$(".menu_clickable").click(function() {
    $(this).attr("disabled", "disabled");
    $("#main").html('<img src="img/spin.gif" class="spin">');
    $("#main").load($(this).attr('rel'), function() {

        // reactivate it after some loading has completed
        $(this).removeAttr("disabled");        
     });
});

You should always reactivate the link within the success callback to ensure that the loading has completed, e.g.:

$.get($(this).attr('rel'), function(html) {
    $("#main").html(html);
    $(this).removeAttr("disabled");
});

EDIT: updated, based on your comment. If your 'action' element is a div, you will have to unbind the click event to prevent re-clicks from having an effect, and re-bind once the loading has completed e.g.:

function handleClick() {
    $(this).unbind("click");
    $("#main").html('<img src="img/spin.gif" class="spin">');
    $("#main").load($(this).attr('rel'), function() {

        // reactivate it after some loading has completed
        $(this).click(handleClick);        
    });        
}
$(".menu_clickable").click(handleClick);
karim79
+1 if you use the `.load()` callback :)
Nick Craver
@Nick - to my knowledge, `load` ensures the inject happens before subsequent statements fire, but it matters for the other methods, e.g. `$.get`, `$.post` etc.
karim79
@karim - Nah it's asynchronous, it's still calling `$.ajax` and using a `success` callback underneath: http://github.com/jquery/jquery/blob/master/src/ajax.js#L15
Nick Craver
But it is not the button it is a DIV (display: block)
Sergio
@Nick - yes, I got that, the phrasing at the beginning of the manual had me a bit confused: "When a successful response is detected (i.e. when textStatus is "success" or "notmodified"), .load() sets the HTML contents of the matched element to the returned data. ". I've fixed it up now.
karim79
+1 - Though the new information from the OP throws a wrench here :)
Nick Craver
`$(this).unbind("click", handleClick);` to prevent any collateral damage!
Nick Craver
Thanks. I updated question with the link of the sample page.Maybe now it will be easier to spot the problem.
Sergio
A: 

do what karim says but check not just that it has been clicked but that function successfully fetched the data. but if your load gets new updates every time it is pressed this wont work.

Another idea would be to assume there is a double click in too many fast clicks so just return false for the dblclick event on the element.

XGreen
A: 

If you're not using input fields (disable them), you can use .data() to keep track of whether a request is in progress, and not respond to successive clicks.

$(".menu_clickable").click(function() {
    var menuItems = $('.menu_clickable');

    if (!menuItems.data('current')) {
        $("#main").html('<img src="img/spin.gif" class="spin">');
        $("#main").load($(this).attr('rel'), function () {
            menuItems.removeData('current');
        });

        menuItems.data('current', true);
    };
});

If you want to allow a number of clicks (?), you can use the same approach, but store a counter rather than a simple boolean value.

Matt
A: 

You can use .live() in this case as well pretty cleanly, like this:

$(".menu_clickable:not(.disabled)").live('click', function() {
  $(this).addClass('disabled');
  $("#main").html('<img src="img/spin.gif" class="spin">')
            .load($(this).attr('rel'), function() {
              $(this).removeClass('disabled');
  });
});

This works by using .live() to listen for the event bubble and run your handler. When you start a load, it adds the "disabled" class to the element, make it no longer satisfy the .live() selector, preventing it from executing. When the load finishes, it removes that class, making it once again satisfy the .live() selector and the handle will work/execute on click again.

As a bonus, you can easily create a matching CSS rule to indicate to the user that it's disabled, like this:

.disabled { color: red; }
Nick Craver