萬盛學電腦網

 萬盛學電腦網 >> 腳本專題 >> javascript >> Js判斷CSS文件加載完畢的具體實現

Js判斷CSS文件加載完畢的具體實現

 在多數情況下我們不需要判斷css文件是否加載成功了,但有些時間這個功能還是需要的,今天我來整理了兼容各種浏覽器的判斷CSS文件加載完畢實現方法與各位分享

要判斷這個 CSS 文件是否加載完畢,各個浏覽器的做法差異比較大,這次要說IE浏覽器做的不錯,我們可以直接通過onload方法來處理CSS加載完成以後的處理:  代碼如下: // 代碼節選至seajs function styleOnload(node, callback) {     // for IE6-9 and Opera     if (node.attachEvent) {       node.attachEvent('onload', callback);       // NOTICE:       // 1. "onload" will be fired in IE6-9 when the file is 404, but in       // this situation, Opera does nothing, so fallback to timeout.       // 2. "onerror" doesn't fire in any browsers!     } }      很遺憾,這次在其他的浏覽器中,想判斷CSS是否加載完成就不是那麼方便了,FF,webkit可以通過node.sheet.cssRules屬性是否存在來判斷是否加載完畢。而且需要使用setTimeout間隔事件輪詢:      代碼如下: // 代碼節選至seajs  function poll(node, callback) {     if (callback.isCalled) {       return;     }     var isLoaded = false;     if (/webkit/i.test(navigator.userAgent)) {//webkit       if (node['sheet']) {         isLoaded = true;       }     }     // for Firefox     else if (node['sheet']) {       try {         if (node['sheet'].cssRules) {           isLoaded = true;         }       } catch (ex) {         // NS_ERROR_DOM_SECURITY_ERR         if (ex.code === 1000) {           isLoaded = true;         }       }     }     if (isLoaded) {       // give time to render.       setTimeout(function() {         callback();       }, 1);     }     else {       setTimeout(function() {         poll(node, callback);       }, 1);     }   }    setTimeout(function() {      poll(node, callback); }, 0);      SeaJS給出的完整的處理是這樣的:    代碼如下: function styleOnload(node, callback) {     // for IE6-9 and Opera     if (node.attachEvent) {       node.attachEvent('onload', callback);       // NOTICE:       // 1. "onload" will be fired in IE6-9 when the file is 404, but in       // this situation, Opera does nothing, so fallback to timeout.       // 2. "onerror" doesn't fire in any browsers!     }     // polling for Firefox, Chrome, Safari     else {       setTimeout(function() {         poll(node, callback);       }, 0); // for cache     }   }   function poll(node, callback) {     if (callback.isCalled) {       return;     }     var isLoaded = false;     if (/webkit/i.test(navigator.userAgent)) {//webkit       if (node['sheet']) {         isLoaded = true;       }     }     // for Firefox     else if (node['sheet']) {       try {         if (node['sheet'].cssRules) {           isLoaded = true;         }       } catch (ex) {         // NS_ERROR_DOM_SECURITY_ERR         if (ex.code === 1000) {           isLoaded = true;         }       }     }     if (isLoaded) {       // give time to render.       setTimeout(function() {         callback();       }, 1);     }     else {       setTimeout(function() {         poll(node, callback);       }, 1);     }   } // 我的動態創建LINK函數 function createLink(cssURL,lnkId,charset,media){      var head = document.getElementsByTagName('head')[0],         linkTag = null;    if(!cssURL){      return false;  }       linkTag = document.createElement('link');  linkTag.setAttribute('id',(lnkId || 'dynamic-style'));  linkTag.setAttribute('rel','stylesheet');  linkTag.setAttribute('charset',(charset || 'utf-8'));  linkTag.setAttribute('media',(media||'all'));  linkTag.setAttribute('type','text/css');     linkTag.href = cssURL;        head.appendChild(linkTag);  } function loadcss(){     var styleNode = createLink('/wp-content/themes/BlueNight/style.css');       styleOnload(styleNode,function(){         alert("loaded");     }); }   在看到seajs的代碼的時候,我立刻想起了我看到Diego Perini的另一個解決方案: 代碼如下: /*  * Copyright (C) 2010 Diego Perini  * All rights reserved.  *  * cssready.js - CSS loaded/ready state notification  *  * Author: Diego Perini <diego.perini at gmail com>  * Version: 0.1  * Created: 20100616  * Release: 20101104  *  * License:  *  http://www.jb51.net * Download:  *  http://javascript.nwbox.com/cssready/cssready.js  */ function cssReady(fn, link) {   var d = document,   t = d.createStyleSheet,   r = t ? 'rules' : 'cssRules',   s = t ? 'styleSheet' : 'sheet',   l = d.getElementsByTagName('link');   // passed link or last link node   link || (link = l[l.length - 1]);   function check() {     try {       return link && link[s] && link[s][r] && link[s][r][0];     } catch(e) {       return false;     }   }   (function poll() {     check() && setTimeout(fn, 0) || setTimeout(poll, 100);   })(); }      其實,如果你讀過jQuery的domready事件的判斷的代碼,原理也類似。也是通過setTimeout輪詢的方式來判斷DOM節點是否加載完畢。 還有,Fackbook則是通過在動態創建的CSS樣式中包含一個固定的樣式,例如#loadcssdom,loadcssdom就是一個高度為1px樣式。然後動態創建一個DOM對象,添加這個loadcssdom樣式。然後也是setTimeout輪詢loadcssdo是否已經有1px的高度了。這個處理方式的解決方案,大家可以下《CSSP: Loading CSS with Javascript – and getting an onload callback.》 而《JavaScript Patterns》的作者Stoyan則在他的博客裡,比較詳細的說明了《When is a stylesheet really loaded?》。 看完了這些,你可能會感歎:汗,判斷CSS是否加載完畢,目前還真不是那麼容易!其實我這裡算是一個拋磚引玉,因為開發中,除了動態加載CSS,我們還要動態加載JavaScript,動態加載HTML的操作,有空我也會寫關於動態加載JavaScript的相關內容,不過在那之前,我建議你看看這些:     《ensure – Ensure JavaScripts/HTML/CSS are loaded on-demand when needed》,這個庫是專門處理動態加載HTML,CSS,JavaScript的。就像作者介紹的那樣:         ensure is a tiny JavaScript library that provides a handy function ensure which allows you to load JavaScript, HTML, CSS on-demand, and then execute your code. ensure www.jb51.net ensures that the relevant JavaScript and HTML snippets are already in the browser DOM before executing your code that uses them.     《
copyright © 萬盛學電腦網 all rights reserved