Ajax正在加载图像

I have a weird issue.

 function sendEmail(settings) {
    var success = false;

    $.ajax({
        type: "POST",
        contentType: settings.contentType,
        data: settings.data,
        url: settings.url,
        dataType: "json",
        async: false,
        beforeSend: function () {
            setTimeout(showOrHideLoadingImage("LoadingImage", "show"), 2000);
            //$("#LoadingImage").show();
        },
        success: function (data) {
            setTimeout(showOrHideLoadingImage("LoadingImage", "hide"), 500);
            //$("#LoadingImage").hide();//Hide loading image

showOrHideLoadingImage function:

 function showOrHideLoadingImage(id, action)
{
    if (action == "show") {
        $("#" + id).show();
    } else {
        $("#" + id).hide();
    }
}

I use this code to send mail, the mail is arriving BUT the ajaxLoading image is not showing

if i put a "debuger" in the "beforeSend" event the image is shown, so I tried to use java script setTimeout function, but with no luck.

*another quetion that I have regarding this, ajaxSuccess and error Global events.

I red that its better to use these events:

if i will use $("#LoadingImage") each time, the mail loading image will shown

but what if I have other id with loading image?

Your showOrHideLoadingImage is being invoked immediately, use an anonymous function in the setTimeout then call your method with params:

setTimeout(function() { 
    showOrHideLoadingImage("LoadingImage", "show"); 
}, 2000);

A couple of things to point out. Developers often put code in the beforeSend method that is intended to execute immediately.

Therefore the following is true;

$.ajax({....
  beforeSend: function () {
     $(....).show();
  }

Is the same thing as.

$(....).show();
$.ajax({....

Secondly, don't hide your loading images in the success handlers of a promise. You want to always remove the loader.

Therefore;

$(....).show();
$.ajax({...}).always(function(){$(...).hide();});

Now, the timeout will always be executed. Even if the AJAX is executed quickly. So if you only want to show the loader after a 2 second delay. You need to keep the timer ID.

var timeID = setTimeout(function() { $(...).show();}, 2000);
$.ajax({...}).always(function(){
    clearTimeout(timeID);
    $(...).hide();
});

In the always callback you remove the timer using the timeID. This prevents it from firing if it hasn't already do so.

if i will use $("#LoadingImage") each time, the mail loading image will shown

Try using the jQuery closest API to find a DOM element relative to what triggered the event.

http://api.jquery.com/closest/

$(document).ready(function(){
 $(document).on('click', '#id', function(){
  sendMail();
 });
})

function sendMail(){
 $('#image').show();
 $.ajax({
   url: url,
   type: 'POST',
   success: function(){
      //DO SOMETHING HERE
   },
   error: function(){
      //DO SOMETHING HERE
   },
   complete: function(){
    $('#image').hide()
   }
 });
}