日志标签 ‘Javascript’

多浏览器下Javascript加载XML文档并解析兼容性问题解决

2011年2月27日

由于Javascript加载并解析XML文档是一个很重要的操作,最近一直尝试写。我自己写了一个测试,发现兼容性的问题很多。基本分为三类:IE,Netscape,Chrome。Chrome虽然是标准浏览器,但是与Netscape这类又不相同。

废话不说,看代码吧

(xmlDoc是一个已创建的XML DOM)

try{

xmlDoc.load(”url/test.xml”);//loading XML for IE and Netscape

}

catch(e)//loading XML for Chrome

{

var xmlhttp = new XMLHttpRequest();

xmlhttp.open(”GET”,” url/test.xml “,false);

xmlhttp.send(null);

xmlDoc=xmlhttp.responseXML;

}

对于IE和Netscape,均可以对XML DOM采用load方法加载。但是Chrome并不支持这一方法,于是用了AJAX的方式返回这个XML。

当时测试的时候,Chrome一直报告这个对象不存在这个方法。

Chrome Help Forum也有人提出了这个问题,以上的解决方案就来源于Pauan的解答,非常感谢Pauan。

解析也有浏览器的问题,解决如下:

function parseXML(doc)//parse the XML document named ‘doc’

{

if(window.ActiveXObject)//if the browser is IE

{

return doc.xml;

}

else//the browser is not IE

{

var oSerializer=new XMLSerializer();//new object XMLSerializer

return oSerializer.serializeToString(doc,’text/xml’);   }

}

通过测试的浏览器:Firefox,IE5.5,6,8(没有测试IE7是因为我的IE Tester的IE7选项有点问题,抱歉),Opera,Chrome,Safari。

最后是创建XML DOM,这个比较简单。代码如下:

if(window.ActiveXObject)//for IE

{

var versions=["MSXML2.DOMDocument.5.0","MSXML2.DOMDocument.4.0","MSXML2.DOMDocument.3.0","MSXML2.DOMDocument","Microsoft.XmlDom"];

for(var i=0;i<versions.length;i++)

{

try{

var xmlDoc= new ActiveXObject(versions[i]);//create XML DOM

}

catch(e){}//failed

}

}

else

{

Var xmlDoc=document.implementation.createDocument(”,”,null);

}

目前就是这样,心得体会是,要学会使用Console,它让你知道你的程序究竟有什么问题。

window.onload在Chrome下停止工作问题

2010年10月25日

最近一直在写原生Javascript小程序。因为我是新手,所以碰到了许多问题,这些问题在我参考的书里完全没有提及,而且在网上也很难找到答案,令我感到非常郁闷。
大部分时候,我在和DOM打交道,而事件处理是DOM中极其重要的东西,然而就是这个重要的东西让人头疼得厉害。
标准的事件模型由W3C制定,而IE这种狗血的东西自己制定了一套事件模型。Microsoft非常恶心的地方就在于,很多东西应该统一标准的,但他们非要玩“非主流”不可。譬如标准的事件模型中:evt.target;IE下:evt.srcElement,这两个其实是等价的。于是我每次为了兼容,都要这么写:
evt.target||evt.srcElement
还有更恶心的:
function addEvent(obj,name,handler,useCapture)
{
if (window.event)//For IE
{
obj.attachEvent(’on’+name,handler);
}
else//For Netscape
{
obj.addEventListener(name,handler,useCapture);
}
}
为了兼容IE的事件模型,不得不多写更多代码。
Microsoft提供了一个event属性来保存当前事件对象,于是就可以把事件对象当成全局变量来使用。我想这是他们自认为自己很高明的地方吧,就和IE 6那烦人的高度自适应一样,基本属于自作聪明,给前端开发者带来很多麻烦。
抱歉我跑题了,以上部分主要用来发泄一下我长久以来对Microsoft的不爽而已。
回到正题Chrome,作为一个Google迷,我很喜欢Chrome浏览器,速度快,界面简洁,还有各种丰富有趣的主题。并且它是支持W3C标准的现代浏览器。
今晚我写了下面这些代码:

function init()
{

}

window.onload=init;

期望能够在页面加载完成后运行 init()函数。
在Firefox,Opera,Safari中都正常运行,甚至一直徘徊在1和3之间的Internet Explorer同学都能够正常运行我程序。结果满怀信心的测试Chrome,它安静的页面顿时把我搞崩溃了。没有执行!
我检查了一遍我代码,没有任何问题。甚至怀疑是我Chrome坏了,或者我把JS功能禁用了。
在网上搜了下,不只是我遇到这个问题,但Google搜出的中文解答中都没有正确的解决办法。最后看到了Chrome官方的HelpForum,虽然是全英文的,但是我还是认真看了(居然还让我看懂了)。总结了下,有两种解决办法,先说麻烦的一种:
If (browserName==”Microsoft Internet Explorer”)
{
window.onload=init;
}
else if (browserName==”Netscape”) //google chrome app.Name
{
window.onload=init( );
}
else
{
window.onload = window.init; // helps with Opera
}
这是一个叫Nikibarudov的人总结的,我测试了下,还是偶尔抽风,不是总能行。
第二种方法很有效,很简单,在页面最下面在调用init( )这个函数就行了。

<html>

<head>

<script type=”text/Javascript” language=”Javascript”>

function init()

{

}

window.onload=init;//这部分还是留着

</script>

</head>

<body>

</body>

<script type=”text/Javascript”>//——-tips——

init( );

</script>

</html>

提供这个方法的人叫Kelly。这样就“手动”的实现了:页面加载完全再执行init()。
我测试了,Firefox,IE,Opera,Safari,当然也包括亲爱的Chrome全都通过了。
不清楚Chrome的JavaScript解释引擎是如何工作的,我猜想它应该不同于其他浏览器。看了篇外文的技术blog,说Chrome的onload不能正常工作,是出于安全性考虑,为了避免页面负荷过载。我仔细想了想,似乎这之间没有必然联系。
同为gecko内核Firefox就没有这个问题,能给出正解的人肯定是熟悉Chrome内核细节的人。我解决了问题,但是却不知道问题的来源,所以我期待着某位高手能够答疑解惑。

用Javascript控制CSS类样式

2009年10月27日

显然,用JS添加和修改DOM元素本身的css属性是很容易的。比如:

document.getElementById(’mydiv’).style.backgroundColor = ‘red’;

但是如果要修改所有 class=”classname1″ 的元素的样式怎么办呢?

使用JQuery的强大的选择器可以很容易的实现。比如:

$(’.classname1′).css(’background-color’,'red’);

但这也是遍历每个元素并修改之。在此之后添加的新的有相同class的元素还是没有变。需要再次遍历修改一次。

现在给出另外一个方法:

往document.body或者document.head里面增加一个style元素,覆盖掉以前的style。比如:

var style = document.createElement(’style’);
style.innerHTML = ‘.classname1 { background-color:red; }’;
document.getElementsByTagName(’head’)[0].appendChild(style);

这个在所有浏览器下面都有用。但是在IE里会有点小问题。如果覆盖的次数多了,新的样式就会失效。解决办法是在刚刚新建的那个style上加一个id值。下次新建的时候,先remove掉那个dom,再append。 JQuery代码如下:

$(’#new_style’).remove(); // 清除以前的样式 ( fix in IE )
$(’<style id=”new_style”>.classname1{ background-color:red;}</style>’).appendTo(document.body); //新增样式,覆盖以前的