火狐浏览器

写了段2级联动菜单,在IE中测试没有问题,在火狐中测试出错,如果连接请求是true根本得不到值,如果改成false就下来菜单就变成undefine,debug也没有出现报错信息,代码如下:

function chang1(){ var url="<%=request.getContextPath()%>/loadmessage1.action"; send_request1(url); } var http_request = false; function createXMLHttpRequest(){ if(window.ActiveXObject){ http_request=new ActiveXObject("Microsoft.XMLHTTP"); }else if(window.XMLHttpRequest){ http_request=new XMLHttpRequest(); } } function send_request1(url){ createXMLHttpRequest(); http_request.onreadystatechange=processRequest1; http_request.open("POST", url,true); http_request.send(null); } // 处理返回信息的函数 function processRequest1(){ if (http_request.readyState == 4) { // 判断对象状态 if (http_request.status == 200||http_request.status==0) { // 信息已经成功返回,开始处理信息 updateselect1(); } } } function updateselect1(){ document.f.cgy.length = 0; document.f.cgy.options[0] = new Option('==请选择=='); var doc = http_request.responseXML; var items=doc.getElementsByTagName('cgy2'); var i=0; for(i;i<items.length;i++) { document.f.cgy.options.add(new Option(items[i].text)); } } }


修改这个方法
function send_request1(url){
createXMLHttpRequest();
http_request.onreadystatechange=processRequest1;
http_request.open("POST", url,true);
http_request.send(null);
}

修改成

[code="java"]
//加上这个方法
function getOs()

{

var OsObject = "";

if(navigator.userAgent.indexOf("MSIE")>0) {

return "MSIE"; //IE浏览器
}
if(isFirefox=navigator.userAgent.indexOf("Firefox")>0){

return "Firefox"; //Firefox浏览器
}
if(isSafari=navigator.userAgent.indexOf("Safari")>0) {

return "Safari"; //Safan浏览器
}
if(isCamino=navigator.userAgent.indexOf("Camino")>0){

return "Camino"; //Camino浏览器
}
if(isMozilla=navigator.userAgent.indexOf("Gecko/")>0){

return "Gecko"; //Gecko浏览器
}

}
function send_request1(url){
createXMLHttpRequest();
var btype=getOs();
http_request.onreadystatechange = (btype!="Firefox")?(processRequest1):(processRequest1());
http_request.open ("POST",url,true);
http_request.send(null);
http_request.onreadystatechange = (btype!="Firefox")?(processRequest1):(processRequest1());

} 

[/code]

先说true的情况:updateselect1()这个函数没有传入http_request对象 就好象你在一个函数中定义了一个变量却在另一个函数中用 这样肯定是错的
再说false的情况:ff在同步调用的时候不支持onreadystatechange 他处理同步的方法是在send之后直接updateselect1() 而不是通过回调调用 呵呵

对了 还有你的http_request.readyState == 4在ff中貌似不可以 得需要写成http_request.readyState < 4

一、问题:
var xmlHttp;
function savetodata(){
createXMLHttpRequest();
var rndcode = new Date().getTime();
var Url ="a.asp?cache="+rndcode
xmlHttp.onreadystatechange = function(){
.....

}
xmlHttp.open ("GET",Url,true);
xmlHttp.send(null);
}
上面的这段代码, xmlHttp.onreadystatechange = function(){.....};可以在FF下执行,但是如果改成
xmlHttp.open ("GET",Url,false);时就不行了,今天被这个问题整的晕头转向。
原因分析:
其一:这时不能用xmlHttp.send(),需要内容,如果没有内容,要用NULL
其二:经测试后发现,onreadystatechange在IE下都很正常,但在FF3下,只能运行readyState=0时的代码。不能运行readyState=4的代码,在网络上找了一个原因:
在ajax的XMLHttpRequest.onreadystatechange方法的差异:在FF中当状态为1(即XMLHttpRequest已经调用open但还没有调用send时),FF则会继续执行onreadystatechange后面的代码,到执行完后面的代码后,在执行onreadystatechange在状态2,3,4的代码,而IE会等待状态2的到了,执行完onreadystatechange中状态2,3,4的代码后,继续执行后面的代码,这样问题就出现了,经常我们在onreadystatechange的代码要处理从服务器上获得的数据(这个数据只有在onreadystatechange的状态为4时,才可以得到),所以这在IE中不存在问题,因为它会等待onreadystatechange状态4到来以后,在执行onreadystatechange后面的数据,但是由于FF不会等到onreadystatechange状态4到来后在执行onreadystatechange后面的代码,所以后面的代码就不能处理从服务器上获得的数据,那该怎么办呢?

解决方法:使用javascript的闭包(这个解决方法是从GMAP中获得灵感的)。我们传递一个函数给onreadystatechange,在这个函数中处理从服务器上返回的数据,但是onreadystatechange是一个无参函数,那该怎么办呢?方法在我前面的Javascript attachEvent传递参数的办法已经介绍 了,这里再稍微介绍一下,就是传递一个参数给onreadystatechange,但是在onreadystatechange中使用return一个无参函数,在这个无参函数中可以使用这个传入的参数。这个方法在IE和FF中都可以正常运行,所以这不失是一个好方法。
这里提到采用闭包,挺复杂,另外网上有采用了在FF下用onload,也是不管用。经过对错误排除,上面摘要提到的原因,才是根本的,也就是说,在FF下,第一次执行完onreadystatechange后,继续执行到send,但后面就不会再回头执行onreadystatechange,一直傻傻的走下去。
我直接改成:
xmlHttp.onreadystatechange = xmlHandle;
xmlHttp.open ("GET",Url,false);
xmlHttp.send(null);
xmlHttp.onreadystatechange = xmlHandle; //这里加一行挡住FF,让它再搞一次。

function xmlHandle(){
if (xmlHttp.readyState < 4){
......
}else if (xmlHttp.readyState == 4 && xmlHttp.status == 200){
var cartResult = Number(xmlHttp.responseText);
if (cartResult == 1){
window.location.href='b.asp';
}else if (cartResult == 2){
......;
}else{
window.location.href='/';
}
}
}
但是这样也不行,原来ff 3改成:xmlHttp.onreadystatechange = xmlHandle();然而加了括号,IE又不行,唉,原来就觉得FF是鸡皮,现在感觉FF纯属一个打着“支持标准”的称号,却是干着浪费程序员时间的垃圾。但手上这个程序又实在重要,没办法,只有再调试看看有没有更简单的办法,如下:
xmlHttp.open ("GET",Url,false);
xmlHttp.send(null);
if(xmlHttp.status==200)
xmlHandle();
这段代码在IE和FF下可以通用。但由于是同步调用,需要在readyState 只有加入浏览器类型分析。
function getOs()
{
var OsObject = "";
if(navigator.userAgent.indexOf("MSIE")>0) {

return "MSIE"; //IE浏览器
}
if(isFirefox=navigator.userAgent.indexOf("Firefox")>0){

return "Firefox"; //Firefox浏览器
}
if(isSafari=navigator.userAgent.indexOf("Safari")>0) {

return "Safari"; //Safan浏览器
}
if(isCamino=navigator.userAgent.indexOf("Camino")>0){

return "Camino"; //Camino浏览器
}
if(isMozilla=navigator.userAgent.indexOf("Gecko/")>0){

return "Gecko"; //Gecko浏览器
}

}
然后把AJAX代码改为:
var rndcode = new Date().getTime();
var CartUrl ="a.asp?cache="+rndcode
var btype=getOs();
xmlHttp.onreadystatechange = (btype!="Firefox")?(xmlHandle):(xmlHandle());
xmlHttp.open ("GET",CartUrl,false);
xmlHttp.send(null);
xmlHttp.onreadystatechange = (btype!="Firefox")?(xmlHandle):(xmlHandle());
总算OVER了,IE6、IE 7、FF通用

这你就自己单步调试看哪一步出问题嘛