2010-08-20 4 views
1

У меня возникла проблема, с которой я пока не смог найти решение.Загрузка анимации не отображается до тех пор, пока не завершится вызов ajax в Safari/Chrome

Я создаю приложение для бронирования ресурсов, которое использует AJAX для обработки информации, предоставленной пользователем, в базовую базу данных. Всякий раз, когда пользователь хочет создать заказ, они заполняют форму с помощью релевантной информации, которая отправляется через AJAX сервлету, который обрабатывает информацию и обновляет базу данных. Поскольку мы включили вариант повторного бронирования, иногда база данных может занять некоторое время для обновления. Таким образом, мы внедрили графику «обработка ...», которая будет отображаться, пока сервлет делает это.

Способ, которым мы реализовали графику обработки, и вызовы ajax отлично работали в firefox, opera и т. Е. Проблема с сафари и хром ... поэтому, вероятно, что-то связано с WebKit.

В Safari/Chrome графический процессор не отображается на странице до тех пор, пока база данных не завершит свою работу, а вызов ajax не вернется ... победит всю цель графика «обработка ...».

Кто-нибудь знает, почему графический объект (который вставлен перед вызовом запроса AJAX) не отображается до тех пор, пока не вернется вызов ajax?

Вот как мы реализовали графические и аякс-вызовы. Это функция, которая вызывает как функцию для создания графики и отправить запрос Аякса:

/** 
* Implements AJAX calls to add/remove bookings from the database 
*/ 
function processBooking(selection, responseID, formElement, removing, fromManager, resourceType) { 

if (!removing) { 
purpose = formElement.purpose.value; 
email = formElement.email.value; 

      /* These values should only be set if the user is an admin otherwise they do not exist so send in the default empty 
      * values to the processing servlet 
      */ 
      if (formElement.repeatEveryUnits != undefined && formElement.repeatFor != undefined && formElement.repeatForUnits != undefined) 
      { 
       repeatEvery = formElement.repeatEveryUnits.value; 
       repeatForAmount = formElement.repeatFor.value; 
       if (repeatForAmount == '') { 
         repeatForAmount = '0'; 
       } 
       repeatForUnit = formElement.repeatForUnits.value; 
      } 
      else 
      { 
       repeatEvery = '0'; 
       repeatForAmount = '0'; 
       repeatForUnit = '0'; 
      } 

} 

    /* Function to be passed in as the callback to our asynchronous request */ 
    callback = function() { 
     document.getElementById(responseID).innerHTML += '<p class="button-small" onclick="removeDiv(\'' + responseID + '\')>Clear</p>'; 
     document.getElementById(responseID).style.padding = '0 0 5px 0'; 
    } 

    /* Parameters that are to be used in our asynchronous request */ 
    postData += parseArray(selection); 
    postData += '&removing=' + removing; 
    postData += '&availability=false'; 
    postData += '&type=' + resourceType; 

    /* Play the loading graphic */ 
    startLoading(); 

    /* Make the call to the servlet */ 
    response = sendAsyncRequest(url,postData,callback,false); 

    /* reset global variables used */ 
    reset(); 

    if ((!removing) || (!fromManager)) 
    { 
     week = document.getElementById("selectedWeek").value; 

     window.location = "../../servlet/ResourceBooking?action=schedule&type=" + resourceType + "&week=" + week; 
    } 

    return response; 
} 

Это код, который вставляет графику:

/** 
*  Begins a loading animation that is to be played while the database does its work 
*/ 
function startLoading() { 

    document.getElementById("container").style.opacity = "0.2"; 
    document.getElementById("cover").style.display = "block"; 
    var newDiv = document.createElement("div"); 

    newDiv.setAttribute("id", "loading"); 
    newDiv.style.height = 120 + "px"; 
    newDiv.style.width = 350 + "px"; 

    newDiv.innerHTML = "<div id='progress'><p id='progress'><img id='progress_image' src='/intranet/images/ajax-loader.gif' alt=''><br/><h3>Processing database...</h3></p></div>"; 
    document.body.appendChild(newDiv); 

    ignoreClicks = true; 
} 

И это код, который делает XMLHttpRequest для вызова AJAX:

function sendAsyncRequest(servletUrl, postData, callback, async) { 

try { 
     asyncRequest = new XMLHttpRequest(); 
} 
catch (e) { 
     // Internet Explorer Browsers 
     try { 
       asyncRequest = new ActiveXObject("Msxml2.XMLHTTP"); 
     } catch(e) { 
       try { 
       asyncRequest = new ActiveXObject("Microsoft.XMLHTTP"); 
       } catch(e){ 
         // Something went wrong 
         alert('Request Failed'); 
         return false; 
       } 
     } 
} 

asyncRequest.onreadystatechange = function() { 
    if (asyncRequest.readyState == 4 && asyncRequest.status == 200) { 
       try { 
           callback(); 
       } 
       catch (e) { 
         // IE fails unless we wrap the string in another element. 
         var childDiv = current_element.getElementsByTagName("div"); 
         if (childDiv.length == 0) { 
           var wrappingDiv = document.createElement('div'); 
           //wrappingDiv.setAttribute("id", current_element.id+"Div"); 
           wrappingDiv.innerHTML = asyncRequest.responseText; 
           current_element.appendChild(wrappingDiv); 
         } 
         else { 
           var wrappingDiv = document.createElement('div'); 
           //wrappingDiv.setAttribute("id", current_element.id+"Div"); 
           wrappingDiv.innerHTML = asyncRequest.responseText; 
           current_element.replaceChild(childDiv[0], wrappingDiv); 
           //childDiv[0].innerHTML = asyncRequest.responseText; 
         } 
       } 
     } 
}; 

asyncRequest.open('POST', servletUrl, async); 

if (postData == null) 
{ 
    asyncRequest.send(null); 
} 
else 
{ 
    asyncRequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); 
    asyncRequest.setRequestHeader("Content-length", postData.length); 
    asyncRequest.setRequestHeader("Connection", "close"); 
    asyncRequest.send(postData); 
} 

return response; 
} 

есть ли что-нибудь о WebKit, что бы предотвратить startLoading DIV динамически добавляется на страницу, прежде чем запрос будет сделано?

Я попытался прокомментировать сам запрос (sendAsyncRequest (...)) после того, как мы загрузим графику, и это будет выглядеть отлично, так что кажется, что что-то происходит с ним, когда мы следим за ним запрос.

любая помощь, я в растерянности ...

Кристен

+0

Ничего себе, как * все * - глобальная переменная в этом коде. Это действительно дурная привычка. – Pointy

+0

это сработало для вас? –

+0

Используя ваши предложенные изменения, графический интерфейс теперь воспроизводится так, как будто, однако, вызов ajax фактически не отправляется на сервлет сейчас. Это то, что я смогу отлаживать, однако. Большое вам спасибо за ваше решение! Я ценю помощь! –

ответ

0

Вы можете установить функцию обратного вызова для события загрузки изображения, а затем только выполнить POST AJAX, когда он загружен. Подобно этому ...

function processBooking(selection, responseID, formElement, removing, fromManager, resourceType) { 
    //...some stuff 
    startLoading(function(){ 
     sendAsyncRequest(url,postData,callback,false); 
    }); 
    //...some more stuff 
} 

function startLoading(callback) { 
    document.getElementById("container").style.opacity = "0.2"; 
    document.getElementById("cover").style.display = "block"; 
    var img = new Image(); 
    img.onload=callback; 
    img.src="/intranet/images/ajax-loader.gif"; 
    var newDiv = document.createElement("div"); 

    newDiv.setAttribute("id", "loading"); 
    newDiv.style.height = 120 + "px"; 
    newDiv.style.width = 350 + "px"; 

    newDiv.innerHTML = "<div id='progress'><p id='progress'><img id='progress_image'  src='/intranet/images/ajax-loader.gif' alt=''><br/><h3>Processing database...</h3></p>  </div>"; 
    document.body.appendChild(newDiv); 

    ignoreClicks = true; 
} 
+0

Спасибо за ответ pixl. Я обязательно попробую! –

2

Его старая нить, но только сегодня у меня была аналогичная проблема. Может быть, это поможет кому-то :).

У меня была аналогичная проблема в IE - у меня есть мой собственный тип загрузки div, который я показываю перед ajax-запросом и скрываю его после загрузки данных. Мой div был показан только на некоторое время (он просто мерцал) после того, как данные уже были загружены.

Что-то вроде этого:

document.getElementById('pnLoaderPanel').style.display = 'block'; 
Task.Refresh(); //method that calls ajax 
document.getElementById('pnLoaderPanel').style.display = 'none'; 

Таким образом, я заметил, что если я ставлю оповещение права после показа DIV, мой DIV виден.Я думаю, что IE как-то не обновлялся правильно, так что я сделал это и теперь его работа отлично:

document.getElementById('pnLoaderPanel').style.display = 'block'; 
setTimeout(Task.Refresh(), 1); //method that calls ajax 
document.getElementById('pnLoaderPanel').style.display = 'none'; 
Смежные вопросы