CSS文件动态加载
来源:互联网 发布:ip交换网络拓扑的设计 编辑:程序博客网 时间:2024/05/21 18:04
前段时间研究了下JS动态加载和执行顺序依赖的东东,把LABJS的源码从头扒了下:LABJS浅析。对于JS加载执行以及下载监控这,项目组在这块做的东西不少,但对于CSS加载这块的质量监控,力度就小得多了。原因很简单:JS下载失败或出错,这个页面基本就废了。CSS下载失败,大部分情况下页面还是可用的,虽然会比较臭。
但对于OPA来说,情况可能就完全不同了,CSS文件加载失败的影响相对就比较大了。
本着生命不息折腾不已的精神,又倒腾了下CSS加载这块的内容,成果如下
删掉注释空行其实代码很少,关于如何测试、API调用都在开头声明了,demo可下载 附件 :)
/** * CSS文件加载器,主要功能:动态加载CSS文件,支持加载完成时候的回调(成功 and 失败 情况下) * 源码实现借鉴:https://github.com/rgrove/lazyload/commit/6caf58525532ee8046c78a1b026f066bad46d32d * 更多关于CSS加载的坑的讨论,见:http://www.phpied.com/when-is-a-stylesheet-really-loaded/ * * 测试方法:1)将文件解压到服务器上(或用fiddler等本地文件替换) 2)访问demo.html即可 * * @example * loadCSS.load('style.css'); * loadCSS.load('style.css', function(){ alert('style.css loaded'); }); * loadCSS.load('style.css', function(obj){ alert('age is '+obj.age); }, {age: 24}); * loadCSS.load(['a.css', 'b.css'], function(){ alert('a.css and b.css are all loaded'); }); * * 更多说明:目前只能判断CSS文件加载事件是否完成,至于是否出现404、5XX等,还判断不了 * 曲线救国:回调里判断CSS里定义的某个样式是否存在/生效,借此判断CSS是否下载成功,如下 * loadCSS.load('sytle.css', function(){ * var div = document.createElement('div'); * div.className = 'pre_defined_class'; //pre_defined_class 为测试用的预定义类,假设为 .pre_defined_class{display:none;} * var value = getStyle(div, 'display'); * if(value=='none'){ * //成功 * }else{ * //失败 * } * }) * * @version 1.0 * @TODO: 1)静态加载的CSS文件的检测(是否成功加载)2)加载配置项 * @author casper chyingp@gmail.com * http://www.cnblogs.com/chyingp * http://www.zcool.com.cn/u/346408 * */var LoadCSS = (function () { //配置项,未实现 var CFG = { POLL_INTERVAL: 50, MAX_TIME: 10 }; var head = document.head || document.getElementsByTagName('head')[0]; var styleSheets = document.styleSheets var env = getEnv(); //获取用户代理信息,为浏览器差异化加载提供判断依据 var queue = []; //CSS加载队列 /* @格式1 queue队列内元素格式 { urls: ['a.css', 'b.css', 'd.css'], callback: function(param){}, //urls里面所有CSS文件加载完成后的回调方法,可选 obj: {age:24} //callback回调方法传入的实参 } */ function indexOf(arr, ele){ var ret = -1; for(var i=0,len=arr.length; i<len; i++){ if(arr[i]==ele) ret = i; } return ret; } /** * @private * @description 返回用户浏览器代理信息,为判断不同浏览器提供依据 * @return {Object} 格式见内部代码 */ function getEnv() { var ua = navigator.userAgent; var env = {}; (env.webkit = /AppleWebKit\//.test(ua)) || (env.ie = /MSIE/.test(ua)) || (env.opera = /Opera/.test(ua)) || (env.gecko = /Gecko\//.test(ua)) || (env.unknown = true); return env; } /** * @private * @description gecko内核的浏览器轮询检测方法 * 参考:http://www.zachleat.com/web/2010/07/29/load-css-dynamically/ * @param {HTMLElement} node style节点,node.nodeName == 'STYLE' * @param {Object} queueObj 见@格式1 */ function pollGecko(node, queueObj) { try { node.sheet.cssRules; } catch (ex) { node.pollCount++; if (node.pollCount < 200) { setTimeout(function () { pollGecko(node, queueObj); }, 50); } else { finishLoading(node.href, queueObj); //用不用略做些延迟,防止神一样的渲染问题?? } return; } finishLoading(node.href, queueObj); } /** * @private * @description webkit内核的浏览器轮询检测方法 * @param {HTMLElement} node link节点,node.nodeName == 'LINK' * @param {Object} queueObj 见@格式1 */ function pollWebKit(node, queueObj) { for(var i=styleSheets.length; i>0; i--){ if(styleSheets[i-1].href===node.href){ finishLoading(node.href, queueObj); return; } } node.pollCount++; //轮询次数加1 if (node.pollCount < 200) { setTimeout(function(){ pollWebKit(node, queueObj); }, 50); } else { finishLoading(node.href, queueObj); } } function checkSucc(className, attr, value){ var div = document.createElement('div'); div.style.cssText += 'height:0; line-height:0; visibility:hidden;'; div.className = className; document.body.appendChild(div); return getComputedStyle(div, attr)==value; } /** * @description 获取节点样式值——只能获取比较简单的样式的值,一些兼容性问题不是重点,在这里不做处理,有兴趣可以看下jquery源码 * @param {HTMLElement} node dom节点 * @param {String} attr 样式名字,如display、visibility等 */ function getComputedStyle(node, attr){ var getComputedStyle = window.getComputedStyle; if(getComputedStyle){ return getComputedStyle(node, null)[attr]; }else if(node.currentStyle){ return node.currentStyle[attr]; }else{ return node.style[attr]; } } /** * @private * @description url对应的CSS文件加载完成时的回调(404也包括在内) * @param {String} url CSS文件的url * @param {Object} queueObj 见@格式1 */ function finishLoading(url, queueObj){ var index = indexOf(queueObj.urls, url); queueObj.urls.splice(index, 1); if(!queueObj.urls.length){ queueObj.callback(queueObj.obj); index = indexOf(queue, queueObj); queue.splice(index, 1); } } /** * @description 加载CSS的方法 * @param {Array} urls 加载的CSS文件名队列 * @param {Function} [callback] CSS文件队列全部加载完的回调 * @param {Object} obj callback的参数 * @param {Object} context * @return {Undefined} */ function loadCSS(urls, callback, obj) { var queueObj = { urls: urls, callback: callback, obj: obj } queue.push(queueObj); var pendingUrls = queueObj.urls; for (var i = 0, len = pendingUrls.length; i < len; ++i) { var url = pendingUrls[i]; var node ; if(env.gecko){ node = document.createElement('style'); }else{ node = document.createElement('link'); node.rel = 'stylesheet'; node.href = url; } //node.setAttribute('charset', 'utf-8'); //设不设置有木有影响,持保留态度 if (env.gecko || env.webkit) { //老版本webkit、gecko不支持onload node.pollCount = 0; queueObj.urls[i] = node.href; //轮询判断的时候用到,因为不同浏览器里面取到的node.href值会不一样,有的只有文件名,有的是完整文件名?(相对路径、绝对路径) if (env.webkit) { //之所以要用轮询,后面讨论,@TODO: 新版本的webkit已经支持onload、onerror,优化下? pollWebKit(node, queueObj); } else { node.innerHTML = '@import "' + url + '";'; //为什么这样做,猛点击这里:http://www.phpied.com/when-is-a-stylesheet-really-loaded/ pollGecko(node, queueObj); } } else { node.onload = node.onerror = function(){ finishLoading(this.href, queueObj); }; } head.appendChild(node); } } //---------------------- 对外接口!--------------------------- return { /** * @description 加载CSS文件 * 考虑:成功回调,错误回调分开? * @param {Array|String} urls 要加载的CSS文件的文件名(相对路径,或绝对路径),比如:'style.css', ['style.css', 'test.css'] * @param {Function} [callback] 可选:文件加载完成后的回调(成功;或失败,如404、500等) * @param {Object} [obj] 可选:回调执行时传入的参数 */ load: function (urls, callback, obj) { loadCSS([].concat(urls), callback || function(){}, obj || {}); } };})();
>>>我是附件,赶紧猛点击
博文转自http://www.cnblogs.com/chyingp/archive/2013/03/01/load_css.html,感谢作者分享
0 0
- 动态加载CSS文件
- CSS文件动态加载
- CSS文件动态加载
- js动态加载css文件
- jquery 动态加载css文件
- 动态加载样式(css)文件
- jQuery动态加载css文件
- 动态加载 css 和javascript文件
- 动态加载外部css或js文件
- ASP.NET动态加载CSS文件
- ASP.NET动态加载CSS文件
- flex动态加载使用css文件实例
- 使用jquery动态加载js,css文件
- JS动态加载JS与CSS文件
- JS动态加载JS与CSS文件
- 使用jquery动态加载js,css文件
- 使用jquery动态加载js,css文件
- JS动态加载JS与CSS文件
- having与group by
- 设计模式之迭代器模式
- Visual Studio系列 卸载visual assist插件和vmware debugger插件的方法
- 累【非技术贴】
- Shell教程(四):条件语句、循环语句、break/continue
- CSS文件动态加载
- hive笔记
- version magic 'xxx ARMvx ' should be 'xxx ARMvx '
- HITOJ Ordered Fractions 1076 (分数排序)
- IO流之----字符流(Reader和Writer)和其它流
- Fragment生命周期 android基础三
- 【PHPRS】一款小巧精悍的PHP RESTful开源框架
- jQueryeasyUI中的一些日期的使用
- Shell教程(五):替代、引用机制、输入输出重定向