【发布时间】:2010-08-20 22:48:11
【问题描述】:
我遇到了一个我还没有找到解决方案的问题。
我正在创建一个资源预订应用程序,它使用 AJAX 将用户提供的信息处理到后端数据库中。每当用户想要创建预订时,他们都会填写一个包含相关信息的表单,这些信息通过 AJAX 发送到处理信息并更新数据库的 servlet。因为我们包含了预订重复选项,所以有时数据库可能需要一段时间才能更新。因此,我们实现了一个“处理...”图形,以便在 servlet 执行操作时显示。
我们实现处理图形和 ajax 调用的方式在 firefox、opera 和 ie 中运行良好,即问题在于 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(...) ),图形看起来会非常好,所以当我们跟进请求时,它似乎正在发生一些事情.
感谢任何帮助,我不知所措......
克里斯汀
【问题讨论】:
-
哇,就像 everything 是该代码中的全局变量。这真是个坏习惯。
-
使用您建议的更改,图形现在可以正常播放,但是 ajax 调用现在实际上并没有发送到 servlet。这是我将能够调试的东西。非常感谢您的解决方案!感谢您的帮助!
-
我猜你的解决方案并没有真正解决问题。它似乎可以工作,因为在我进行更改后实际上并没有处理 ajax 调用。但是,一旦我再次接到工作电话,直到电话完成后,图像才会再次显示。还有其他想法吗? WebKit 会在 ajax 调用期间停止所有其他处理吗?同样,这个问题只发生在基于 WebKit 的浏览器中。
-
好的,我无法重现正在发生的事情。这是一个有效的示例jsbin.com/owisu3/2 为了简单起见,我已经删除了很多错误处理
标签: javascript ajax google-chrome safari webkit