【问题标题】:Best way to disable a link after clicking on it so that ajax call should not be made单击链接后禁用链接的最佳方法是不应该进行 ajax 调用
【发布时间】:2012-12-24 10:33:53
【问题描述】:

我正在使用以下代码发送一个可以正常工作的 ajax 请求,但是当用户多次单击链接时会产生问题,所以我想禁用我的链接,以便在用户第二次单击时不会调用 ajax .

.html.erb

<%= link_to("Sports", "#", :class => "school_activity", :p_type => "Sport", :o_type => "")%>

javascript

jQuery(function () {
  jQuery('.school_activity').click(function () {
    link = jQuery(this);
    p_type = link.attr('p_type');
    o_type = link.attr('o_type');
    jQuery('.i-link a').removeClass('stream_wall_select');
    jQuery.ajax({
      type:"GET",
      url:'<%= some_path(@school) %>',
      data:'format=js&p_type=' + p_type + '&tagged_type=' + o_type,
      success:function (response) {
        jQuery('#s_activity_div').html(response);
      }
    });
  })
})

我不想设置参数 true/false 并依赖它发送 ajax 请求。

我想要一些非常通用的东西,可能适用于我网站上的所有 ajax 链接。

【问题讨论】:

  • @salil 只需放置 $('.my-link').click(function () {return false;});在 ajax 调用中的成功回调中

标签: jquery ajax ruby-on-rails-3.1 disable-link


【解决方案1】:

在点击发生时移除href属性,并在点击完成时将其添加回来。

...
  jQuery('.school_activity').click(function () {
    var link = $(this).attr('href');
    jQuery(this).removeAttr('href');
   ...
    jQuery.ajax({ .... });
   ...
    jQuery(this).attr("href",link);
...

更新

使用 jQuery 方法 one() 确保某些内容只执行一次。

将处理程序附加到元素的事件。每个元素最多执行一次处理程序。

jQuery('.school_activity').one('click', function () {
    jQuery.ajax({
        ...
    });
});

注意:这将只运行一次,无论 AJAX 是否失败。

【讨论】:

  • 它不会起作用,因为禁用的属性将被立即删除
  • 对不起,我也习惯为submit 按钮这样做。修好了。
【解决方案2】:

第一个简单通用的解决方案 - 使用同步调用:

jQuery.ajax({
      type:"GET",
      async: false,
...

在这种情况下,浏览器将等待调用完成。但它有时会导致页面冻结(在等待时)

第二种解决方案是使用自定义标志/属性,尽管您讨厌它(查看 in_progress 属性):

jQuery(function () {
  jQuery('.school_activity').click(function () {
    if( $(this).attr('in_progress') ) return;

    link = jQuery(this);
    p_type = link.attr('p_type');
    o_type = link.attr('o_type');
    jQuery('.i-link a').removeClass('stream_wall_select');

    $(this).attr('in_progress', 1);
    var link = this;

    jQuery.ajax({
      type:"GET",
      url:'<%= some_path(@school) %>',
      data:'format=js&p_type=' + p_type + '&tagged_type=' + o_type,
      success:function (response) {
        jQuery('#s_activity_div').html(response);
      }, 
      complete: function(){ $(link).removeAttr('in_progress'); }
    });
  })
})

为了使它成为一个健壮且通用的解决方案,我们可以为这种情况创建一个自定义函数:

function waCall( element, ajaxParams, beforeAjaxCallback, afterAjaxCallback ) {

    if( $(element).attr('in_progress') ) return; 

    var link = $(element);
    $(link).attr( 'in_progress' );

    ajaxParams['complete'] = function() { $(link).removeAttr('in_progress');
                             if( afterAjaxCallback ) afterAjaxCallback( link ); };

    if( beforeAjaxCallback ) beforeAjaxCallback(link);

    $.ajax( ajaxParams );
}


jQuery(function () {
      jQuery('.school_activity').click(function () {
          waCall( this, {
              type:"GET",
              url:'<%= some_path(@school) %>',
              data:'format=js&p_type=' + p_type + '&tagged_type=' + o_type,
              success:function (response) {
                  jQuery('#s_activity_div').html(response);
              }
            }, function(link) {
                var p_type = link.attr('p_type');
                var o_type = link.attr('o_type');
                jQuery('.i-link a').removeClass('stream_wall_select');
            }
      }
});

【讨论】:

  • 从 jQuery 1.8 开始,不推荐使用 async: false。
【解决方案3】:

你可以使用像

这样的标志
$(function(){
 $flag=false;

 $("#idOfYourLink").click(function(e){
   e.preventDefault();
   $flag=true;
   if(!$flag){
     $.ajax({
       ...
       success:function(){
           $flag=false;
         }//success ends
       });//ajax ends
    }//flag chk if ends
  });//click handler ends
});//document ready ends

编辑:

因为你特别提到

我不想做诸如设置参数真/假之类的事情并依赖它发送> ajax 请求。

您可以简单地解除点击事件处理程序的绑定,并在ajax调用的成功回调中重新附加;

【讨论】:

  • @arttronics:OP 特别说:I don't want to do something like setting the parameter true/false and depend on it send ajax request.
  • 这就是为什么我建议在答案末尾绑定和重新绑定事件
  • @PranavKapoor,这就是我没有说优秀答案的原因!干杯!
【解决方案4】:

简单的删除和添加触发器类

$(document).on('click', '.click', function(e){
        e.preventDefault();

        $(this).removeClass('click');

        $.ajax({
            url: "/question",
            method: "POST",  
            dataType: 'json',
            cache: false,
            data: form_data,
            success: function (response){

            }
        }).done(function() { $(this).addClass('click');  } );

    });

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-31
    • 2021-06-02
    • 2021-09-21
    • 2017-12-11
    • 2011-09-23
    • 2012-10-05
    • 1970-01-01
    相关资源
    最近更新 更多