您现在的位置: 万盛学电脑网 >> 程序编程 >> 脚本专题 >> javascript >> 正文

Js判断CSS文件加载完毕的具体实现

作者:佚名    责任编辑:admin    更新时间:2022-06-22

 在多数情况下我们不需要判断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.     《