Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Internet Explorer not executing Javascript in order

I'm developing a web app that needs to do some backend processing while still displaying the information on screen. Obviously this is best suited for AJAX, which I'm using. However, prior to beginning the AJAX request, I'm making a few visual changes via Javascript. Specifically:

document.getElementById('calc').innerHTML = 'Calculating...'; document.getElementById('calc').disabled = true;

I then go on to call a servlet via AJAX.

This works fine in Firefox. However in Internet Explorer (version 8), the visual changes never take effect. The app just sits there for a minute or two until the AJAX processing is done. It seems like the AJAX code is executing before the page changes, but I don't know why that would be.

Any assistance would be greatly appreciated.

EDIT: Here's my best effort at a Short, Self Contained, Correct, Example

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Cache-Control" content="no-cache">
<script>
var inEdit = 0;
var calcCurrent = false; 
function recalc() {
var xmlhttp=new XMLHttpRequest();
if (xmlhttp==null)
{
  var tmp = "Your browser does not support XML! ";
  tmp += "Please contact your Technical Support division for information on how to upgrade.";
  alert(tmp);
}
else
{
  document.getElementById('calc').innerHTML = 'Calculating...';
  document.getElementById('calc').disabled = true;
  var url = "http://www.nzherald.co.nz/";
  xmlhttp.open("GET",url,false);
  xmlhttp.send(null);
  if (xmlhttp.responseText.indexOf("Success")>=0) {
    alert(xmlhttp.responseText);
  }
  else
    alert(xmlhttp.responseText);
  document.getElementById('calc').value = 'Recalculate';
  document.getElementById('calc').disabled = false;
}
}
</script>
</head>
<body>
<a id='calc' class='Button' href="javascript:recalc()" >Recalculate</a>
</body>
</html>

The only issue example with this is that this URL returns almost instantly. On my app it's pointing to a page that does database processing for about a minute, and so the problem is a lot more obvious.

like image 815
enjiner Avatar asked Jan 18 '12 00:01

enjiner


2 Answers

You are passing "false" for the async parameter to xmlhttp.open() call. Because the stack has not unwound since you set the innerHTML property of the calc element, IE has not had a chance to repaint the screen.

You have a few options.

  1. Restructure your code such that you make the ajax call async and get the result via a callback notification.

  2. OR.... Set the innerHTML property on calc, then call setTimeout with a delay of 0 and a callback function that is written to call xmlhttp.open as you have it now. This will allow the stack to unwind and IE will repaint the DOM changes followed by your ajax call executing. Below is a hacked up version of your code to demonstrate what I am talking about.

Below is some hacked up code demonstrating #2.

var xmlhttp;

function recalc() {
    xmlhttp=new XMLHttpRequest();
    if (xmlhttp==null)
    {
      var tmp = "Your browser does not support XML! ";
      tmp += "Please contact your Technical Support division for information on how to upgrade.";
      alert(tmp);
    }
    else
    {
      document.getElementById('calc').innerHTML = 'Calculating...';
      document.getElementById('calc').disabled = true;
      setTimeout(recalc_start, 0);
    }
}

function recalc_start() {
  var url = "http://www.nzherald.co.nz/";

  xmlhttp.open("GET",url,false);
  xmlhttp.send(null);
  if (xmlhttp.responseText.indexOf("Success")>=0) {
    alert(xmlhttp.responseText);
  }
  else {
    alert(xmlhttp.responseText);
  }
  document.getElementById('calc').value = 'Recalculate';
  document.getElementById('calc').disabled = false;
}
like image 56
selbie Avatar answered Nov 10 '22 08:11

selbie


Those two lines of code are very straightforward. The are two things that comes to mind:

  1. Do you have the ID defined for another element. Can you double check that calc is not used anywhere else in the page? Preferably by doing a Ctrl+F in View Source.
  2. Validate your HTML. Make sure you are not missing any closing tags or quotes in an attribute.
like image 38
epignosisx Avatar answered Nov 10 '22 08:11

epignosisx