JavaScript相容性小議

來源:互聯網
上載者:User
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" onclick="alert(t1.value)">
<!-- 2 -->
<input id="t1"><input type="button"
value="click me" onclick="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的封裝問題!這篇結合自己的經驗和網上朋友的經驗湊成的文章就到這裡了。不知道大家感覺怎樣?有沒有得到收益?如果有一點點,我的工作就完成了!

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.