views:

45

answers:

2

I'm currently using the following code for my read more buttons:

$(document).ready(function() {
  $("a.more-link").attr("href", "");
  $("a.more-link").attr("onclick", "return false;");  

  $('.readmore').each(function(index) {
    var $link = $(this);
    $(".readmore").prependTo('.' + $link.attr("id") + ' > #bottominfo');
  });

  $('.readmore').click(function() {  
    var $link = $(this);
    if ( $link.attr("alt") == "read more" ) {
      $('.' + $link.attr("id") + ' > #maincontent').load($link.attr("title") + ' #mainarticle', function(index) {
            $('.' + $link.attr("id") + ' > #maincontent').hide();  
            $('.' + $link.attr("id") + ' > #maincontent').slideToggle('slow');
          });

      $('.' + $link.attr("id") + ' > #maincontent').attr("class", $link.attr("id"));

      $link.attr('alt','read less');      
    } else {
      $('#'+ $link.attr("id") + ' > .' + $link.attr("id")).hide();
      $link.attr('alt','read more'); 
    }
    return false;
 });
});

The problem I'm having is that if the user double clicks (or more) on the button it calls the function multiple times.

How do I make the button non-clickable until the .load() have finished?

Thanks!

A: 

Could you not just run the function on .load instead?

$(document).load(function() {
  $("a.more-link").attr("href", "");
  $("a.more-link").attr("onclick", "return false;");  

  $('.readmore').each(function(index) {
    var $link = $(this);
    $(".readmore").prependTo('.' + $link.attr("id") + ' > #bottominfo');
  });

  $('.readmore').click(function() {  
    var $link = $(this);
    if ( $link.attr("alt") == "read more" ) {
      $('.' + $link.attr("id") + ' > #maincontent').load($link.attr("title") + ' #mainarticle', function(index) {
            $('.' + $link.attr("id") + ' > #maincontent').hide();  
            $('.' + $link.attr("id") + ' > #maincontent').slideToggle('slow');
          });

      $('.' + $link.attr("id") + ' > #maincontent').attr("class", $link.attr("id"));

      $link.attr('alt','read less');      
    } else {
      $('#'+ $link.attr("id") + ' > .' + $link.attr("id")).hide();
      $link.attr('alt','read more'); 
    }
    return false;
 });
});
BenWells
This doesn't seem to help either. I'm not sure why it isn't just smoothly loading.
henryprescott
+1  A: 

The easiest would be to add a loading class to the link. I have also just done a quick clean up on your code. I didn't look into how it works but i'm sure if you spend a bit more time you can make it a lot more efficient

$(document).ready(function() {
  $("a.more-link").attr("href", "")
                  .attr("onclick", "return false;");  

  $('.readmore').each(function(index) {
    var $link = $(this);
    //wouldn't this call all the elements with "readmore" class????
    $(".readmore").prependTo('.' + $link.attr("id") + ' > #bottominfo');
  });

  $('.readmore').click(function() {
    var $link = $(this);

    //check if it has already been clicked
    if($link.hasClass("loading")) return false;
    //add the loading class
    $link.addClass("loading");


    if ( $link.attr("alt") == "read more" ) {
      $('.' + $link.attr("id") + ' > #maincontent').load($link.attr("title") + ' #mainarticle', function(index) {
            $('.' + $link.attr("id") + ' > #maincontent').hide()
                                                         .slideToggle('slow');

            //it's done now and we can remove the loading class so we can click it again
            $link.removeClass("loading");

          }).attr("class", $link.attr("id"));

      $link.attr('alt','read less');      
    } else {
      $('#'+ $link.attr("id") + ' > .' + $link.attr("id")).hide();
      $link.attr('alt','read more');

      //add it here as well
      $link.removeClass("loading");
    }
    return false;
 });
});

Tips: I notice you call the same selectors multiple times. Always check the api doc and see what the methods you are calling do return. Most of them do return the element back, so then you can call the next method without $()

Example: $("div").hide().slideToggle('slow');

Mouhannad
Sometimes it loads nicely, and other times it seems to be jerky and completely reset the page.
henryprescott
check at the bottom of the code, i add it one more line
Mouhannad
to test it, add alert() after $link.addClass("loading"); you will see one alert message even if you double click before the content has been loaded
Mouhannad
Yes, great, thank you very much!
henryprescott
No problem at all! I don't know if this is the best method but I usually do this if I want a quick block
Mouhannad