一、方法引用來源和應(yīng)用
此動態(tài)加載css方法 loadCss,剝離自Sea.js,并做了進(jìn)一步的優(yōu)化(優(yōu)化代碼后續(xù)會進(jìn)行分析)。
因為公司項目需要用到懶加載來提高網(wǎng)站加載速度,所以將非首屏渲染必需的css文件進(jìn)行動態(tài)加載操作。
二、優(yōu)化后的完整代碼
/*
* @function 動態(tài)加載css文件
* @param {string} options.url -- css資源路徑
* @param {function} options.callback -- 加載后回調(diào)函數(shù)
* @param {string} options.id -- link標(biāo)簽id
*/
function loadCss(options){
var url = options.url,
callback = typeof options.callback == "function" ? options.callback : function(){},
id = options.id,
node = document.createElement("link"),
supportOnload = "onload" in node,
isOldWebKit = +navigator.userAgent.replace(/.*(?:AppleWebKit|AndroidWebKit)//?(/d+).*/i, "$1") < 536, // webkit舊內(nèi)核做特殊處理
protectNum = 300000; // 閾值10分鐘,一秒鐘執(zhí)行pollCss 500次
node.rel = "stylesheet";
node.type = "text/css";
node.href = url;
if( typeof id !== "undefined" ){
node.id = id;
}
document.getElementsByTagName("head")[0].appendChild(node);
// for Old WebKit and Old Firefox
if (isOldWebKit || !supportOnload) {
// Begin after node insertion
setTimeout(function() {
pollCss(node, callback, 0);
}, 1);
return;
}
if(supportOnload){
node.onload = onload;
node.onerror = function() {
// 加載失敗(404)
onload();
}
}else{
node.onreadystatechange = function() {
if (/loaded|complete/.test(node.readyState)) {
onload();
}
}
}
function onload() {
// 確保只跑一次下載操作
node.onload = node.onerror = node.onreadystatechange = null;
// 清空node引用,在低版本IE,不清除會造成內(nèi)存泄露
node = null;
callback();
}
// 循環(huán)判斷css是否已加載成功
/*
* @param node -- link節(jié)點
* @param callback -- 回調(diào)函數(shù)
* @param step -- 計步器,避免無限循環(huán)
*/
function pollCss(node, callback, step){
var sheet = node.sheet,
isLoaded;
step += 1;
// 保護(hù),大于10分鐘,則不再輪詢
if(step > protectNum){
isLoaded = true;
// 清空node引用
node = null;
callback();
return;
}
if(isOldWebKit){
// for WebKit < 536
if(sheet){
isLoaded = true;
}
}else if(sheet){
// for Firefox < 9.0
try{
if(sheet.cssRules){
isLoaded = true;
}
}catch(ex){
// 火狐特殊版本,通過特定值獲知是否下載成功
// The value of `ex.name` is changed from "NS_ERROR_DOM_SECURITY_ERR"
// to "SecurityError" since Firefox 13.0. But Firefox is less than 9.0
新聞熱點
疑難解答