【问题标题】:ajax progressive enhancement: How to prevent multiple requestsajax渐进增强:如何防止多个请求
【发布时间】:2013-01-10 14:17:08
【问题描述】:

这是我正在做的简化版本。

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

<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,它将“加载”类添加到我要替换的 html 容器中,并在 ajax 成功时删除该类。这可以正常工作,但如果用户尝试发出多个请求,则性能很差。我猜这是因为它每次都会触发一个事件,即使它没有做太多。

【问题讨论】:

    标签: ajax preventdefault progressive-enhancement


    【解决方案1】:

    您可以更改代码以将“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)

    根据 Dan 的 cmets,已更新上述代码以确保正确性。也就是说,您可以通过将 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');
      });
    

    【讨论】:

    • 如果我错了,请纠正我,但这样做的问题是,如果用户单击多次,href 将导致整个页面加载,因为没有任何东西可以阻止它。
    • 这就是e.preventDefault(); 的用途,它阻止了默认操作,对于具有href 属性的锚标记,默认操作是跟随链接。
    • 我明白这一点,但这就是正在发生的事情:点击时检查它是否是“a”标签并且没有加载类,如果为真,则阻止默认并添加加载类。如果你双击它,它会忽略 preventDefault 因为它有一个加载类。如果用户单击多个链接,我认为它不会阻止多个请求。
    • 嘿...丹!我的错误,但您仍然可以使用on() 绑定至少使事件处理更加高效。我会更新我的代码。
    • 实际上,现在我想起来了,你可以完全移除锚来避免这种情况。再次,我将更新代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-08
    • 2015-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多