我遇到了一个我尚未找到解决方案的问题。
我正在创建一个资源预订应用程序,它使用AJAX处理用户提供给后端数据库的信息。每当用户想要创建预订时,他们就会填写一份包含相关信息的表单,该表单通过AJAX发送到处理信息并更新数据库的servlet。因为我们已经包含了预订重复选项,有时数据库可能需要一段时间才能更新。因此,我们实现了一个“处理...”图形,以便在servlet完成它时显示。
我们实现处理图形和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;
}
这是为AJAX调用生成XMLHttpRequest的代码:
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 :(得分: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';
答案 1 :(得分:0)
您可以为图像加载事件设置回调,然后仅在加载时执行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;
}