ajax渐进增强:如何防止多个请求

时间:2013-01-10 14:17:08

标签: ajax preventdefault progressive-enhancement

以下是我正在做的简化版本。

我有一个像这样的标准菜单:

<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>

在准备好文档时,我正在调用一个函数来阻止链接进入任何地方并绑定点击事件以进行ajax加载:

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

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

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

                   AJAX STUFF HERE
                }
        });

});

我的问题是什么是防止多个请求的好方法。

我的第一次尝试,点击,我有一个条件,检查一类“加载”。如果为false,则将“loading”类添加到我正在替换的html容器中,并在ajax成功时删除该类。这样可以正常工作,但如果用户尝试发出多个请求,则性能很差。我猜这是因为它每次都会发射一个事件,即使它没有做太多。

1 个答案:

答案 0 :(得分:2)

您可以将代码更改为使用特定类“on”:

$('#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'); }
    });
  }
});

现在只有一个绑定(效率更高),当锚没有“加载”类时,它将采取ajax操作。请注意,这将需要jQuery 1.7 +

jQuery .on() documentation

编辑(x2)

Per Dan的评论,上述代码已更新,以确保正确性。也就是说,您可以通过将html和js更改为以下内容来提高效率。请注意,这意味着没有JavaScript的用户只需关注链接。

<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');
  });