前段时间研究了下JS动态加载和执行顺序依赖的东东,把LABJS的源码从头扒了下:LABJS浅析。对于JS加载执行以及下载监控这,项目组在这块做的东西不少,但对于CSS加载这块的质量监控,力度就小得多了。原因很简单:JS下载失败或出错,这个页面基本就废了。CSS下载失败,大部分情况下页面还是可用的,虽然会比较臭。
但对于OPA来说,情况可能就完全不同了,CSS文件加载失败的影响相对就比较大了。
本着生命不息折腾不已的精神,又倒腾了下CSS加载这块的内容,成果如下,鉴于今天晚上11点才下班回家现在已经很困,就直接上代码了,详细分析后面补上~
删掉注释空行其实代码很少,关于如何测试、API调用都在开头声明了,demo可下载 附件 :)
1 34 var LoadCSS = (function () { 35 36 //配置项,未实现 37 var CFG = { 38 POLL_INTERVAL: 50, 39 MAX_TIME: 10 40 }; 41 42 var head = document.head || document.getElementsByTagName('head')[0]; 43 var styleSheets = document.styleSheets 44 var env = getEnv(); //获取用户代理信息,为浏览器差异化加载提供判断依据 45 var queue = []; //CSS加载队列 46 54 55 56 function indexOf(arr, ele){ 57 var ret = -1; 58 for(var i=0,len=arr.length; i0; i--){126 127 if(styleSheets[i-1].href===node.href){128 finishLoading(node.href, queueObj);129 return;130 }131 }132 133 node.pollCount++; //轮询次数加1134 135 if (node.pollCount < 200) {136 setTimeout(function(){137 pollWebKit(node, queueObj);138 }, 50);139 } else {140 finishLoading(node.href, queueObj);141 }142 }143 144 function checkSucc(className, attr, value){145 var div = document.createElement('div');146 div.style.cssText += 'height:0; line-height:0; visibility:hidden;';147 div.className = className;148 document.body.appendChild(div);149 150 return getComputedStyle(div, attr)==value;151 }152 153 158 function getComputedStyle(node, attr){159 var getComputedStyle = window.getComputedStyle;160 if(getComputedStyle){161 return getComputedStyle(node, null)[attr];162 }else if(node.currentStyle){163 return node.currentStyle[attr];164 }else{165 return node.style[attr];166 }167 }168 169 175 function finishLoading(url, queueObj){176 var index = indexOf(queueObj.urls, url);177 queueObj.urls.splice(index, 1);178 179 if(!queueObj.urls.length){180 queueObj.callback(queueObj.obj);181 182 index = indexOf(queue, queueObj);183 queue.splice(index, 1);184 }185 }186 187 195 function loadCSS(urls, callback, obj) {196 var queueObj = {197 urls: urls,198 callback: callback,199 obj: obj200 }201 queue.push(queueObj);202 203 var pendingUrls = queueObj.urls;204 for (var i = 0, len = pendingUrls.length; i < len; ++i) {205 206 var url = pendingUrls[i];207 var node ;208 if(env.gecko){209 node = document.createElement('style');210 }else{211 node = document.createElement('link');212 node.rel = 'stylesheet';213 node.href = url;214 }215 //node.setAttribute('charset', 'utf-8'); //设不设置有木有影响,持保留态度216 217 if (env.gecko || env.webkit) { //老版本webkit、gecko不支持onload218 219 node.pollCount = 0;220 queueObj.urls[i] = node.href; //轮询判断的时候用到,因为不同浏览器里面取到的node.href值会不一样,有的只有文件名,有的是完整文件名?(相对路径、绝对路径) 221 222 if (env.webkit) { //之所以要用轮询,后面讨论,@TODO: 新版本的webkit已经支持onload、onerror,优化下?223 224 pollWebKit(node, queueObj);225 226 } else {227 228 node.innerHTML = '@import "' + url + '";'; //为什么这样做,猛点击这里:http://www.phpied.com/when-is-a-stylesheet-really-loaded/229 pollGecko(node, queueObj);230 }231 232 } else {233 234 node.onload = node.onerror = function(){235 finishLoading(this.href, queueObj);236 };237 }238 239 head.appendChild(node);240 }241 }242 243 //---------------------- 对外接口!---------------------------244 return {245 246 253 load: function (urls, callback, obj) {254 loadCSS([].concat(urls), callback || function(){}, obj || {});255 }256 257 };258 })(); 原文:https://www.cnblogs.com/chyingp/archive/2013/03/01/load_css.html



