Type Mismatch problem with onreadystatechange using AJAX and IE 6
What a nightmare this one was. After 5 days and about 40 some hours I finally figured out my problem with IE 6 and the onreadystatechange event handler.
I needed to build a useful tooltip rollover for the CSA Travel Protection – Travel Insurance website. The pages that reference travel insurance definitions of certain types of coverages direct our customers off the purchase page. In an attempt to keep them on the purchase page we needed to come up with a way to show title tags that do not get cut off (Mozilla, Opera) but reference one source instead of hundreds of static pages.
With this task I opted to use Overlib tooltip script along with AJAX that reads an xml file on our server and returns an XMLHttpRequest object with the responseXML.documentElement.
After trying many different ways of doing this I decided upon using a Javascript object with strings and methods to do all the work. I was able to get everything working beautifully in all browsers except IE. The problem seemed to rear its ugly head when IE tried to run this command:
this.requester.onreadystatechange = this.actionOnReady();
I kept getting a “Type Mismatch” error in Script Debugger. I tried over hundreds of combinations of possible solutions that I got off of Google, Yahoo, MSN, but on the 5th day and did a more generic search for “onreadystatechange function”. This led me to Experts Exchange; so I logged in with my companies login and read the solution to an article on Google.
I found a certain way of creating a function that I hadn’t tried yet and !WhaBamm! it worked. I now can display these fancy tooltips in all browsers! The following piece of code is all I had to do to get IE to function properly. I had to detect if the browser is Internet Explorer, then create a new function “new Function(myFunction())”. I had tried doing “function(){this.actionOnReady();};” but that is what returned the “Type Mismatch” error.
if (navigator.appName=="Microsoft Internet Explorer"){
this.requester.onreadystatechange = new Function(this.actionOnReady());
}else{
this.requester.onreadystatechange = this.actionOnReady();
}
The full code from my ajax.js file is here:
// www.phoeniix.com - Use of AJAX on the CSA site
// Create the tooltip object
AjaxTooltip = new Object();
AjaxTooltip.responsestring = "actionOnReady not run";
AjaxTooltip.requester;
// 1st Step - Pass the function the url of the page and what tip to look for and return a string
AjaxTooltip.sendRequest = function(xmlurl)
{
// Set Vars
this.xmlurl = xmlurl;
// Run Objects
this.initializeRequestor();
this.requester.open("GET",this.xmlurl,true);
this.requester.send(null);
}
// 2nd Step - This gets the data
AjaxTooltip.getTip = function(name)
{
// Set Vars
this.name = name;
// Run Objects
if (navigator.appName=="Microsoft Internet Explorer"){
this.requester.onreadystatechange = new Function(this.actionOnReady());
}else{
this.requester.onreadystatechange = this.actionOnReady();
}
}
// SUPPORTING FUNCTIONS ///////////////////////////////////////////////////////////////////////////
// Set up the XMLHttpRequest object
AjaxTooltip.initializeRequestor = function()
{
this.requester = null;
/* Check for running connections */
if (this.requester != null && this.requester.readyState != 0 && this.requester.readyState != 4){
this.requester.abort();
}
// branch for native XMLHttpRequest object
if(window.XMLHttpRequest) {
try {
this.requester = new XMLHttpRequest();
} catch(e) {
this.requester = null;
return false;
}
// branch for IE/Windows ActiveX version
} else if(window.ActiveXObject) {
try {
this.requester = new ActiveXObject("Msxml2.XMLHTTP");
} catch(e) {
try {
this.requester = new ActiveXObject("Microsoft.XMLHTTP");
} catch(e) {
this.requester = null;
return false;
}
}
}
}
// Update the text in a HTML element if ready
AjaxTooltip.actionOnReady = function()
{
if (this.requester.readyState==4) {
if (this.requester.status == 200) {
this.processData();
if (document.getElementById){
document.getElementById("overDiv").innerHtml = this.responsestring;
}else if(document.all){
document.all("overDiv").innerHtml = this.responsestring;
}
} else {
if (document.getElementById){
document.getElementById("overDiv").innerHtml = "Not able to retrieve description";
}else if(document.all){
document.all("overDiv").innerHtml = "Not able to retrieve description";
}
}
}
}
// Get the data from the childnode of the specified name attribute
AjaxTooltip.processData = function()
{
this.responsestring = "No Definitions Found";
//Code to do xml processing
var response = this.requester.responseXML.documentElement;
for (i=0; i< response .childNodes.length; i++){
if (response.childNodes.item(i).nodeName=="definition" && response.childNodes.item(i).attributes[0].value==this.name){
this.responsestring = response.childNodes.item(i).childNodes.item(0).data;
//alert(this.responsestring);
return;
}
}
// Code to do string processing
//this.responsestring = this.requester.responseText;
}
Thanks!!! The functionality worked fine, just hated seeing the darn JavaScript error in IE. It took me over an hour to find this page and thank goodness I kept looking. Thanks a million.