Загрузка анимации отображается только после завершения вызова ajax в Safari / Chrome - PullRequest
1 голос
/ 21 августа 2010

Я столкнулся с проблемой, которую пока не смог найти решение.

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

То, как мы реализовали обработку графики и ajax-вызовов, отлично работает в Firefox, Opera и т. Д., Проблема в Safari и Chrome ... так что, вероятно, что-то делать с WebKit.

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

Кто-нибудь знает, почему рисунок (который вставляется до вызова AJAX-запроса) не отображается до тех пор, пока не будет возвращен вызов 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 что-нибудь, что мешало бы динамическому добавлению div startLoading на страницу до того, как будет сделан запрос?

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

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

Кристен

Ответы [ 2 ]

2 голосов
/ 06 августа 2012

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

У меня была похожая проблема в 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';
0 голосов
/ 21 августа 2010

Вы можете установить обратный вызов для события загрузки изображения, а затем выполнить ajax POST только после его загрузки. Вот так ...

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;
 }
...