1. 程式人生 > >關於js中的onreadystatechange學習筆記

關於js中的onreadystatechange學習筆記

轉載自:https://www.cnblogs.com/wkylin/archive/2012/08/22/2651011.html


問題描述

onreadystatechange 事件通常用在基於 XMLHttpRequest 物件的 AJAX 應用中,當的該物件的 load state 改變時,會觸發此事件。

但在 IE 中 onreadystatechange 事件是其私有實現的,用於資料載入的 IMG、SCRIPT 和 LINK 標記,常常被誤用 onreadystatechange 事件而導致在非 IE 瀏覽器中無法得到預期結果。

造成的影響

onreadystatechange 事件處理在各瀏覽器支援不一致,可能會導非預期結果。

受影響的瀏覽器
    
問題分析

onreadystatechange 事件是微軟對 IE 瀏覽器的私有事件擴充,所有元素都存在 onreadystatechange 事件。
下列元素物件總可以觸發此事件,因為他們均會載入資料:APPLET,DOCUMENT,FRAME,FRAMESET,IFRAME,IMG,LINK,OBJECT,SCRIPT 和 XML 元素。
其他元素物件僅當 DHTML Behavior 被追加後會觸發 onreadystatechange 事件。

其具體資訊可以參照 MSDN 說明:http://msdn.microsoft.com/en-us/library/ms536957(VS.85).aspx。

本文中將主要以 IMG、SCRIPT、LINK 這三個元素物件為例來檢測瀏覽器對他們的 onreadystatechange 事件支援程度。

首先,分析以下程式碼,將 onreadystatechange 事件作為內聯事件分別寫於 IMG、SCRIPT 和 LINK 標記中:

<script> function OnStateChangeImage(image) {
document.getElementById ('img-info').innerHTML += '<br />readyState: ' + image.readyState;
}
function OnStateChangeScript(script) {
document.getElementById ('script-info').innerHTML += '<br />readyState: ' + script.readyState;
}
function OnStateChangeLink(link) {
document.getElementById ('link-info').innerHTML += '<br />readyState: ' + link.readyState;
} </script> <span id="link-info" >The link is loading.</span><br /> <span id="img-info" >The image is loading.</span><br /> <span id="script-info">The script is loading.</span><br /> <link rel="stylesheet" type="text/css" href="http://www.cnblogs.com/http://www.cnblogs.com/http://www.cnblogs.com/css/article.css" onreadystatechange="OnStateChangeLink(this)" /> <img src="w3c.png" onreadystatechange="OnStateChangeImage (this)" /> <script src='http://code.jquery.com/jquery-1.4.js' onreadystatechange="OnStateChangeScript(this)"></script>

在各瀏覽器輸出如下:

        
    The image is loading.
The image readyState: complete     The image is loading.
    The script is loading.
The script readyState: loading
The script readyState: loaded
The script readyState: complete     The scirpt is loading
    The link is loading.
The link readyState: complete     The link is loading

即:非 IE 瀏覽器均不支援觸發 IMG、SCRIPT 和 LINK 標記的內聯 onreadystatechange 事件。

讓後,下面將分析動態建立的 IMG、SCRIPT 標記的在各瀏覽器中能否觸發 onreadystatechange 事件:

function loadJS(url) { var domScript = document.createElement('script'); domScript.onreadystatechange = function() { var divElement = document.createElement('div'); divElement.appendChild(document.createTextNode('readyState:'+ domScript.readyState +' 動態建立的 SCRIPT 標記可以觸發 onreadystatechange 事件')); document.body.appendChild(divElement); } domScript.src = url; document.getElementsByTagName('head')[0].appendChild(domScript);} function loadIMG(url) { var domImage = document.createElement('img'); domImage.onreadystatechange = function() { var divElement = document.createElement('div'); divElement.appendChild(document.createTextNode('readyState:'+ domImage.readyState +' 動態建立的 IMG 標記可以觸發 onreadystatechange 事件')); document.body.appendChild(divElement); } domImage.src = url; document.getElementsByTagName('head')[0].appendChild(domImage);} function loadCSS(url) { var domLink = document.createElement('link'); domLink.onreadystatechange = function() { var divElement = document.createElement('div'); divElement.appendChild(document.createTextNode('readyState:'+ domLink.readyState +' 動態建立的 LINK 標記可以觸發 onreadystatechange 事件')); document.body.appendChild(divElement); } domLink.rel = 'stylesheet'; domLink.type = 'text/css'; domLink.href = url; document.getElementsByTagName('head')[0].appendChild(domLink);} window.onload=function (){ //執行動態載入外部 JS 檔案 loadJS('http://code.jquery.com/jquery-1.4.js'); //執行動態載入圖片檔案 loadIMG('w3c.png'); //執行動態載入css檔案 loadCSS('http://www.cnblogs.com/http://www.cnblogs.com/../css/article.css');}

各瀏覽器輸出如下:

            
    readyState:complete 動態建立的 IMG 標記可以觸發 onreadystatechange 事件     readyState:undefined 動態建立的 IMG 標記可以觸發 onreadystatechange 事件     無內容輸出
    readyState:loading 動態建立的 SCRIPT 標記可以觸發 onreadystatechange 事件
readyState:loaded 動態建立的 SCRIPT 標記可以觸發 onreadystatechange 事件     readyState:loaded 動態建立的 Script 標記可以觸發 onreadystatechange 事件     無內容輸出
    readyState:complete 動態建立的 LINK 標記可以觸發 onreadystatechange 事件     readyState:undefined 動態建立的 LINK 標記可以觸發 onreadystatechange 事件     無內容輸出

可見,此次測試中,除 IE 瀏覽器外,Opera 對於動態建立的 IMG、SCRIPT 和 LINK 標記也可以觸發 onreadystatechange 事件,但他對不同元素載入過程中觸發該事件的頻率以及 readyState 狀態值的支援細節又不同於 IE。

【注】:對於 MSDN 中其他標記或物件在非 IE 瀏覽器中支援 onreadystatechange 事件的情況,本文將不再一一驗證,讀者如有興趣可以自行測試。

解決方案

在現行 W3C 標準規範中僅有 XmlHttpRequest 物件中存在 onreadystatechange 事件 ( 請參考 XMLHttpRequest 規範 )。

對於其他元素或物件請慎用 onreadystatechange 事件,因為他只有 IE 瀏覽器支援,而 Opera 瀏覽器則只是部分支援。

如果使用 onreadystatechange 是為了處理指令碼載入(回撥)的問題,請參考 BX9013: 動態引入的外部 JS 檔案在各瀏覽器中的載入順序不一致 一文“解決方案”中的內容。