Question

Here's a simplified version of what I'm doing.

I have a standard menu like so:

<ul id="menu">
   <li><a href="/link1.html">Link 1</a></li>
   <li><a href="/link2.html">Link 2</a></li>
   <li><a href="/link3.html">Link 3</a></li>
</ul>

On document ready, I'm calling a function to stop the links from going anywhere and binding click events for ajax loads:

$('#menu a').click(function (e) {
        e.preventDefault();

        var link = $(this).attr('href');

        $.ajax({
                url: link,
                dataType: 'html',
                success: function (html) {

                   AJAX STUFF HERE
                }
        });

});

My question is what is a good way to prevent multiple requests.

My first try at this, on click, I have a conditional that checks for a class of "loading". If false it adds the class of "loading" to the container of html that I'm replacing and removing the class on ajax success. This works fine, but has poor performance if the user tries to make multiple requests. I'm guessing this is because it's firing an event each time, even if it's not doing much.

Was it helpful?

Solution

You could change your code to use "on" with a specific class:

$('#menu').on('click', 'a', (function (e) {
  e.preventDefault();
  var link = $(this);
  if (!link.hasClass('loading') {
    link.addClass('loading');
    var href = link.attr('href');
    $.ajax({
      url: href,
      dataType: 'html',
      success: function (html) {
        // AJAX STUFF HERE
      },
      complete: function() { link.removeClass('loading'); }
    });
  }
});

You only have one binding now (more efficient) and it will take the ajax action when the anchor does not have a "loading" class. Note that this will require jQuery 1.7+

jQuery .on() documentation.

EDIT (x2)

Per Dan's comments, the above code was updated for correctness. That said, you could make this slightly more efficient by changing the html and js to the following. Note that this means that users without JavaScript will simply follow the links.

<ul id='menu'>
  <li><a href='/link1.php'>Link 1</a></li>
  <li><a href='/link2.php'>Link 2</a></li>
  <li><a href='/link3.php'>Link 3</a></li>
</ul>

$('#menu')
  .on('click', 'a:not(.loading)', (function () {
    var link = $(this).addClass('loading');
    $.ajax({
      url: link.attr('data-href'),
      dataType: 'html',
      success: function (html) {
        // AJAX STUFF HERE
      },
      complete: function() { link.removeClass('loading'); }
    })
  })
  // Remove anchor tag href to eliminate possibility of following the link versus ajax load
  .find('a').each(function() {
    $(this).attr('data-href', $(this).attr('href')).removeAttr('href');
  });
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top