提交点击时,Jquery自动加载gif和按钮禁用

时间:2010-05-20 23:11:36

标签: javascript jquery

是否可以自动显示/隐藏ajax加载gif,同时禁用/启用提交按钮? (当提交按钮是样式的< a>而非输入类型=提交时)

目前提交时,我这样做:

$("#save_button_id").click(function () {
        if ($('#save_button_id').hasClass('ui-state-disabled')) return false;
        Save();
});

function Save() {
StartAjax($("#save_button_id"));
$.ajax({
        success: function (data) {
            EndAjax($("#save_button_id"));
            // etc...
        },
        error: function (xhr, status, error) {
            EndAjax($("#save_button_id"));
            // etc ...
        }
});
}

function StartAjax(button) {
    DisableButtonClick(button);
    $("#ajaxLoad").show();
}

function EndAjax(button) {
    EnableButtonClick(button);
    $("#ajaxLoad").hide();
}

我已经看过一些地方谈论如何使用.ajaxStart()来自动显示加载gif,但是是否也可以找到对按钮(样式的< a>标记)的引用单击,并自动禁用/启用它?

重点是不必每次都手动输入Start / EndAjax,并确保应用程序在任何地方都保持一致。

修改

到目前为止,没有一个答案提供自动化 - 任何解决方案(如我上面的当前一个)你必须在每个$ .ajax()之前和之后手动输入开始/结束导致维护问题:它很容易忘记将开始/结束放在一些$ .ajax()调用旁边,如果您想稍后更改它的工作方式,则需要通过每一个来进行更改。

编辑2 - 澄清点.delegate()建议

您说“您可以将事件处理程序附加到任何元素” - 但我想将其附加到每个按钮元素(DRY!):所以我已经修改了你的建议的第一部分:

$('div#buttons a.ui-icon').each(function(index) {
    $(this).ajaxStart(function() {
        $("#ajaxLoad").show();
    });
});

这解决了第一个问题,即如何显示任何按钮的加载.gif,而不必重复键入“$(”#ajaxLoad“)。show()”无处不在$ .ajax()调用

下一部分是如何在单击时禁用任何按钮(同样没有重复代码) - 你建议使用.delegate()。但在您的示例中,每次单击按钮都会调用Save()方法。 (我更改了选择器以匹配我的HTML)

$('div#buttons a.ui-icon').delegate('button:not(.ui-state-disabled)', 'click', function() {
   $(this).toggleClass('ui-state-disabled');
   Save();  // this line needs replacing with a call to $(this).something
});

这个问题是$(this)并不总是保存按钮(选择器返回所有按钮),它可能是删除按钮或取消按钮等。所以调用$(this).toggleClass是很好,但调用Save()意味着你正在调用错误的函数。所有这些按钮都有一个.click方法:

$("#SaveButton").click(function () {
    Save();
});

$("#DeleteButton").click(function () {
    Delete();
});

所以这是原始的点击功能,需要调用它所说的$(this)。上面的东西。在这一点上它应该调用原始点击 - 或者说它应该冒泡到原始的.click更正确。 .delegate必须更通用,原始.click将提供特定的实现。

3 个答案:

答案 0 :(得分:7)

实际上结果非常简单:我已将其包含在每个页面运行的helper.js文件中:

$(document).ready(function () {
    $('div#buttons a.fm-button').each(function (index) {
        $(this).ajaxStart(function () {
            $("#ajaxLoad").show();
            DisableButtonClick($(this));
        });
        $(this).ajaxStop(function () {
            $("#ajaxLoad").hide();
            EnableButtonClick($(this));
        });
    });
});

现在,无论何时在任何页面上单击任何ajax-y按钮,都会禁用按钮并显示ajax加载gif。当ajax呼叫结束时,它们将返回正常状态。每次调用.ajax()时都会重复输入代码。

答案 1 :(得分:2)

您可以将事件处理程序附加到任何元素;所以对于你的保存按钮:

$(this).ajaxStart(function() {
  $("#ajaxLoad").show();
});

现在,您可以侦听页面上每个按钮的click事件,并从该元素调用ajax函数:

$('div').delegate('button:not(.ui-state-disabled)', 'click', function() {
   $(this).toggleClass('ui-state-disabled');
   Save();
});

$.delegate()函数侦听每个没有.ui-state-disabled类的元素的click事件。触发事件时,它会将该按钮的类切换为禁用,调用Save函数并触发$ .ajaxStart()事件。该事件将显示您的动画ajax gif。

我假设你的按钮都包含在这个例子的div中。许多人想要修改代码,以便$('div').delegate...实际指定按钮的包含元素。我也假设你正在使用jQuery 1.4.2。

您应该能够使用$.ajaxStop()功能将所有内容重新还原。

答案 2 :(得分:0)

$("#save_button_id").click(function () {
  if ($('#save_button_id').hasClass('ui-state-disabled')) {
    return false;
  } else {
    // add disabled class
    $('#save_button_id').addClass('ui-state-disabled');

    // optionally disable the button if it's an input button
    $('#save_button_id').attr('disabled','disabled');

    // show ajax loader
    $("#ajaxLoad").show();

    $.ajax({
      url: 'ajax/stuff.html',
      success: function(data) {
        // do stuff

        // re-enable button
        $('#save_button_id').removeClass('ui-state-disabled');

        // optionally re-enable the button if it's an input button
        $('#save_button_id').attr('disabled','');

        // hide ajax loader
        $("#ajaxLoad").hide();
      },
      error: function (xhr, status, error) {
        // do stuff

        // re-enable button
        $('#save_button_id').removeClass('ui-state-disabled');

        // optionally re-enable the button if it's an input button
        $('#save_button_id').attr('disabled','');

        // hide ajax loader
        $("#ajaxLoad").hide();
      });
  }

  // prevent default action, if any
  return false;
});

编辑:并将它们放在一个函数中:


function processing(status) {
  if (status == 1) {
    // add disabled class
    $('#save_button_id').addClass('ui-state-disabled');

    // optionally disable the button if it's an input button
    $('#save_button_id').attr('disabled','disabled');

    // show ajax loader
    $("#ajaxLoad").show();
  } else {
    // re-enable button
    $('#save_button_id').removeClass('ui-state-disabled');

    // optionally re-enable the button if it's an input button
    $('#save_button_id').attr('disabled','');

    // hide ajax loader
    $("#ajaxLoad").hide();
  }
}

然后调用该函数:

$("#save_button_id").click(function () {
  if ($('#save_button_id').hasClass('ui-state-disabled')) {
    return false;
  } else {
    processing(1);

    $.ajax({
      url: 'ajax/stuff.html',
      success: function(data) {
        // do stuff

        processing(0);
      },
      error: function (xhr, status, error) {
        // do stuff

        processing(0);
      });
  }

  // prevent default action, if any
  return false;
});