JavaScript兼容性小议
大中小
大家好,非常高兴和大家一起研究这个做web(网页)都会遇到的技术问题。很多人说只要支持Internet Explorer[以下全部简称ie]就可以了,其他的浏览器可以忽略!其实是这样的,无论是从哪个统计看,ie的市场占有率都只有80%左右。为了这个问题,上次我还和php群的兄弟讨论了好久,他们还把自己的统计给我看:只有70%用ie!
大家没有想到吧,其他浏览器竟然占有这么多份额,我也一样惊讶,那么,自己在开发时为什么不好好学习一下各个浏览器之间的差异呢?所以我花了很多时间去整理和归纳这些差异,当然不可能都是自己领悟出来的,那是武林高手做的事情,于是自己找了点资料,还有作了一些测试,当然这也是这篇文章的基础。好了废话不多说,现在就开始代码之旅,以下我总结了一些零散、常见的问题,和大家一起研究分享,希望对大家有所帮助。
第一:onload
网页加载完执行的函数,这个代码是从十大常用javascript的函数里面摘取的,当然有其他的实现方法,但这个函数写的真的非常巧妙。从效率方面也是一个非常值得使用的函数!
以下就是具体代码:
//--------------------------------------------------------
function addLoadEvent(func) {
var oldonload = window.onload;
if (typeof window.onload != 'function') {
window.onload = func;
}
else {
window.onload = function() {
oldonload();
func();
}
}
}
//--------------------------------------------------------
我不想一句一句的分析这个addLoadEvent,那是高手们很难接受的!我们就来说说它的兼容性!请看函数中window.onload,作者为什么不用document.body.onload呢?那是因为在Firefox[以下全部简称ff]下document.body.onload是undefined(未定义),把一个函数赋值给undefined既不会发生什么事情,也不算出错!这个是让人头痛!好的,知道兼容性的厉害了吧?那么,以后在编写代码时注意一下就好了!
第二:body
这个body对象也是困扰我们的东西,叫它对象不知道对不对?我不是学计算机专业的,专业术语还真不大清楚!
以下就是具体代码:
//--------------------------------------------------------
function getPageScroll(){
var yScroll;
if (self.pageYOffset) {
yScroll = self.pageYOffset;
}
// Explorer 6 Strict
else if (document.documentElement && document.documentElement.scrollTop){
yScroll = document.documentElement.scrollTop;
} else if (document.body) {// all other Explorers
yScroll = document.body.scrollTop;
}
arrayPageScroll = new Array('',yScroll)
return arrayPageScroll;
}
//--------------------------------------------------------
这个函数作用是:浏览器滚动条滚动的高度读取。这是从lightbox中摘录的,读读这段代码,看到三次判断:
1.if (self.pageYOffset)对ff进行判断处理;
2.if (document.documentElement && document.documentElement.scrollTop)是对网页标准(xHTML 1.1 DTD)的判断,这里要说明一下:在加入 xHTML 1.1 DTD 文件头时document.body.scrollTop之类的值往往是0,而这个是很难被调试察觉的(我曾因此困惑很久,这里吐血传授经验啦!);
3.则是我们常用document.body.scrollTop。
从这三次判断,可以想象作者思维的严密了!当然这是程序员的共性!
第三:attachEvent/addEventListener
这里是比较直接的区别,可是太多的直接却造成了编程的困扰,这不禁使人想起:到底有多少这样的直接不同函数?他们的差别到底在哪里?毕竟大家的大脑空间有限,这么多怎么记?可是这些是必须记住的!没事,这篇文章里常见的js兼容性都提到了,可以作为“家居旅行,随身携带”的小手册!
以下就是具体代码:
//--------------------------------------------------------
_observeAndCache: function(element, name, observer, useCapture) {
if (!this.observers) this.observers = [];
if (element.addEventListener) {
this.observers.push([element, name, observer, useCapture]);
element.addEventListener(name, observer, useCapture);
} else if (element.attachEvent) {
this.observers.push([element, name, observer, useCapture]);
element.attachEvent('on' + name, observer);
}
}
//--------------------------------------------------------
意思是给对象添加事件。这是Sam Stephenson的prototype中类的一部分,举这段代码,不是让你去慢慢分析那个prototype.js文件,只是说明在ie和Opera下就可以使用obj.attachEvent(),但在ff下却只能使用obj.addEventListener()。
类似区别的还有:
detachEvent/removeEventListener
parentElement/parentNode
insertAdjacentElement/appendChild
srcElement/target
onmousewheel/DOMMouseScroll
clientY/pageY
第四:对象引用
1.getElementById
请看以下代码:
<!-- 1 -->
<input id="t1"><input type="button"
value="click me" οnclick="alert(t1.value)">
<!-- 2 -->
<input id="t1"><input type="button"
value="click me" οnclick="alert(document.getElementById('t1').value)">
两个都是获取文本框的值,但后者的兼容性就比前者好!对于IE来说,一个HTML 元素的ID可以直接在脚本中当作变量名来使用,而ff中不可以。
getElementById这个函数是非常有用、通用的函数,所以在引用对象时我们要尽量使用它!
2.var
请看以下代码:
//--------------------------------------------------------
echo=function(str){
document.write(str);
}
//--------------------------------------------------------
这个函数在ie上运行正常,ff下却报错了,而在echo前加上var就正常了,这个就是我们提到var的目的。
3.[]
document.forms(”formName”) 改为 document.forms[”formName”]目的:现有代码中许多集合类对象取用时使用 (),ie 能接受,ff 却不能。
4.frame的引用
ie可以通过id或者name访问这个frame对应的window对象,而mf只可以通过name来访问这个frame对应的window对象。
第五:脚本执行
让我们分别做个试验,请出ie和ff分别运行一下下面一段js:
//--------------------------------------------------------
o={
foo: function(){
alert("fly");
}
};
with (o) {
bar();
function bar(){
alert("fly");
}
foo();
}
//--------------------------------------------------------
IE下,上面的代码成功输出fly,ff报错:bar未定义!
当然这是一个小小的试验,大家很明显的看出ie和ff的支持执行的情况:ie脚本预解释执行,ff脚本顺序执行!这是javascript编写和设计时必须注意的东西!
第六:XMLHttpRequest对象
请看以下代码
//--------------------------------------------------------
function createRequest(){
if(typeof XMLHttpRequest!="undefined")? {
return new XMLHttpRequest();
}else if(typeof ActiveXObject!="undefined"){
var xmlHttp_ver? = false;
var xmlHttp_vers = [
"MSXML2.XmlHttp.5.0",
"MSXML2.XmlHttp.4.0",
"MSXML2.XmlHttp.3.0",
"MSXML2.XmlHttp",
"Microsoft.XmlHttp"
];
if(!xmlHttp_ver){
for(var i=0;i<xmlHttp_vers.length;i++){
try{
new ActiveXObject(xmlHttp_vers[i]);
xmlHttp_ver = xmlHttp_vers[i];
break;
}catch(oError){;}
}
}
if(xmlHttp_ver){
return new ActiveXObject(xmlHttp_ver);
}else{
throw new Error("Could not create XML HTTP Request.");
}
}else{
throw new Error("Your browser doesn't support an XML HTTP Request.");
}
}
//--------------------------------------------------------
意思是:得到XMLHttpRequest对象,是喜悦村里的一个兄弟写的。在ie下,一句new ActiveXObject("MSXML2.XMLHTTP")就可以搞定的东西,但这里我们花了这么多行代码来解决兼容性问题,这个函数作者更从原理入手:xmlHttp_vers 应该从版本高的往版本低的写,这样建立对象的数据调用的是你机子上安装过的最高版本的MSXML2.XmlHttp。十分巧妙和有效地得到了对象!
好了,其实关于javascript兼容性的例子还有很多,我们无法罗列所有,这里做了个简单介绍,更多的只能在编程工程中去慢慢体会了!当然本文仅仅讨论了js的兼容性,同时css的兼容性问题也是不可忽视的!解决兼容性最好的方法就是封装!那么下次有机会再和大家一起研究一下css的兼容性和js的封装问题!这篇结合自己的经验和网上朋友的经验凑成的文章就到这里了。不知道大家感觉怎样?有没有得到收益?如果有一点点,我的任务就完成了!
大中小
大家好,非常高兴和大家一起研究这个做web(网页)都会遇到的技术问题。很多人说只要支持Internet Explorer[以下全部简称ie]就可以了,其他的浏览器可以忽略!其实是这样的,无论是从哪个统计看,ie的市场占有率都只有80%左右。为了这个问题,上次我还和php群的兄弟讨论了好久,他们还把自己的统计给我看:只有70%用ie!
大家没有想到吧,其他浏览器竟然占有这么多份额,我也一样惊讶,那么,自己在开发时为什么不好好学习一下各个浏览器之间的差异呢?所以我花了很多时间去整理和归纳这些差异,当然不可能都是自己领悟出来的,那是武林高手做的事情,于是自己找了点资料,还有作了一些测试,当然这也是这篇文章的基础。好了废话不多说,现在就开始代码之旅,以下我总结了一些零散、常见的问题,和大家一起研究分享,希望对大家有所帮助。
第一:onload
网页加载完执行的函数,这个代码是从十大常用javascript的函数里面摘取的,当然有其他的实现方法,但这个函数写的真的非常巧妙。从效率方面也是一个非常值得使用的函数!
以下就是具体代码:
//--------------------------------------------------------
function addLoadEvent(func) {
var oldonload = window.onload;
if (typeof window.onload != 'function') {
window.onload = func;
}
else {
window.onload = function() {
oldonload();
func();
}
}
}
//--------------------------------------------------------
我不想一句一句的分析这个addLoadEvent,那是高手们很难接受的!我们就来说说它的兼容性!请看函数中window.onload,作者为什么不用document.body.onload呢?那是因为在Firefox[以下全部简称ff]下document.body.onload是undefined(未定义),把一个函数赋值给undefined既不会发生什么事情,也不算出错!这个是让人头痛!好的,知道兼容性的厉害了吧?那么,以后在编写代码时注意一下就好了!
第二:body
这个body对象也是困扰我们的东西,叫它对象不知道对不对?我不是学计算机专业的,专业术语还真不大清楚!
以下就是具体代码:
//--------------------------------------------------------
function getPageScroll(){
var yScroll;
if (self.pageYOffset) {
yScroll = self.pageYOffset;
}
// Explorer 6 Strict
else if (document.documentElement && document.documentElement.scrollTop){
yScroll = document.documentElement.scrollTop;
} else if (document.body) {// all other Explorers
yScroll = document.body.scrollTop;
}
arrayPageScroll = new Array('',yScroll)
return arrayPageScroll;
}
//--------------------------------------------------------
这个函数作用是:浏览器滚动条滚动的高度读取。这是从lightbox中摘录的,读读这段代码,看到三次判断:
1.if (self.pageYOffset)对ff进行判断处理;
2.if (document.documentElement && document.documentElement.scrollTop)是对网页标准(xHTML 1.1 DTD)的判断,这里要说明一下:在加入 xHTML 1.1 DTD 文件头时document.body.scrollTop之类的值往往是0,而这个是很难被调试察觉的(我曾因此困惑很久,这里吐血传授经验啦!);
3.则是我们常用document.body.scrollTop。
从这三次判断,可以想象作者思维的严密了!当然这是程序员的共性!
第三:attachEvent/addEventListener
这里是比较直接的区别,可是太多的直接却造成了编程的困扰,这不禁使人想起:到底有多少这样的直接不同函数?他们的差别到底在哪里?毕竟大家的大脑空间有限,这么多怎么记?可是这些是必须记住的!没事,这篇文章里常见的js兼容性都提到了,可以作为“家居旅行,随身携带”的小手册!
以下就是具体代码:
//--------------------------------------------------------
_observeAndCache: function(element, name, observer, useCapture) {
if (!this.observers) this.observers = [];
if (element.addEventListener) {
this.observers.push([element, name, observer, useCapture]);
element.addEventListener(name, observer, useCapture);
} else if (element.attachEvent) {
this.observers.push([element, name, observer, useCapture]);
element.attachEvent('on' + name, observer);
}
}
//--------------------------------------------------------
意思是给对象添加事件。这是Sam Stephenson的prototype中类的一部分,举这段代码,不是让你去慢慢分析那个prototype.js文件,只是说明在ie和Opera下就可以使用obj.attachEvent(),但在ff下却只能使用obj.addEventListener()。
类似区别的还有:
detachEvent/removeEventListener
parentElement/parentNode
insertAdjacentElement/appendChild
srcElement/target
onmousewheel/DOMMouseScroll
clientY/pageY
第四:对象引用
1.getElementById
请看以下代码:
<!-- 1 -->
<input id="t1"><input type="button"
value="click me" οnclick="alert(t1.value)">
<!-- 2 -->
<input id="t1"><input type="button"
value="click me" οnclick="alert(document.getElementById('t1').value)">
两个都是获取文本框的值,但后者的兼容性就比前者好!对于IE来说,一个HTML 元素的ID可以直接在脚本中当作变量名来使用,而ff中不可以。
getElementById这个函数是非常有用、通用的函数,所以在引用对象时我们要尽量使用它!
2.var
请看以下代码:
//--------------------------------------------------------
echo=function(str){
document.write(str);
}
//--------------------------------------------------------
这个函数在ie上运行正常,ff下却报错了,而在echo前加上var就正常了,这个就是我们提到var的目的。
3.[]
document.forms(”formName”) 改为 document.forms[”formName”]目的:现有代码中许多集合类对象取用时使用 (),ie 能接受,ff 却不能。
4.frame的引用
ie可以通过id或者name访问这个frame对应的window对象,而mf只可以通过name来访问这个frame对应的window对象。
第五:脚本执行
让我们分别做个试验,请出ie和ff分别运行一下下面一段js:
//--------------------------------------------------------
o={
foo: function(){
alert("fly");
}
};
with (o) {
bar();
function bar(){
alert("fly");
}
foo();
}
//--------------------------------------------------------
IE下,上面的代码成功输出fly,ff报错:bar未定义!
当然这是一个小小的试验,大家很明显的看出ie和ff的支持执行的情况:ie脚本预解释执行,ff脚本顺序执行!这是javascript编写和设计时必须注意的东西!
第六:XMLHttpRequest对象
请看以下代码
//--------------------------------------------------------
function createRequest(){
if(typeof XMLHttpRequest!="undefined")? {
return new XMLHttpRequest();
}else if(typeof ActiveXObject!="undefined"){
var xmlHttp_ver? = false;
var xmlHttp_vers = [
"MSXML2.XmlHttp.5.0",
"MSXML2.XmlHttp.4.0",
"MSXML2.XmlHttp.3.0",
"MSXML2.XmlHttp",
"Microsoft.XmlHttp"
];
if(!xmlHttp_ver){
for(var i=0;i<xmlHttp_vers.length;i++){
try{
new ActiveXObject(xmlHttp_vers[i]);
xmlHttp_ver = xmlHttp_vers[i];
break;
}catch(oError){;}
}
}
if(xmlHttp_ver){
return new ActiveXObject(xmlHttp_ver);
}else{
throw new Error("Could not create XML HTTP Request.");
}
}else{
throw new Error("Your browser doesn't support an XML HTTP Request.");
}
}
//--------------------------------------------------------
意思是:得到XMLHttpRequest对象,是喜悦村里的一个兄弟写的。在ie下,一句new ActiveXObject("MSXML2.XMLHTTP")就可以搞定的东西,但这里我们花了这么多行代码来解决兼容性问题,这个函数作者更从原理入手:xmlHttp_vers 应该从版本高的往版本低的写,这样建立对象的数据调用的是你机子上安装过的最高版本的MSXML2.XmlHttp。十分巧妙和有效地得到了对象!
好了,其实关于javascript兼容性的例子还有很多,我们无法罗列所有,这里做了个简单介绍,更多的只能在编程工程中去慢慢体会了!当然本文仅仅讨论了js的兼容性,同时css的兼容性问题也是不可忽视的!解决兼容性最好的方法就是封装!那么下次有机会再和大家一起研究一下css的兼容性和js的封装问题!这篇结合自己的经验和网上朋友的经验凑成的文章就到这里了。不知道大家感觉怎样?有没有得到收益?如果有一点点,我的任务就完成了!