2015-11-16 248 views
1

我試圖加載額外的css文件中使用這樣的代碼:延遲加載

var doc = document, 
    head = doc.getElementsByTagName('head')[0], 
    link = doc.createElement('link'), 
    file = link.cloneNode(true); 

file.type = 'text/css'; 
file.rel = 'stylesheet'; 

file.onload = function() { 
    alert('css file is loaded!'); 
}; 
file.onerror = function() { 
    // 404 error 
    alert('Script ' + url + ' wasn\'t loaded! Check file URL'); 
}; 

file.href = 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css'; 
head.appendChild(file); 

http://jsfiddle.net/d3bcp4dy/1/

完美的CH,FF,歌劇20+等工作

但它不工作在Safari5.1,IOS 5.1,Android 4.2及更少!

爲什麼onload/onerror事件不適用於.css文件?

p.s.如果我將文件更改爲.js - onloadonerror事件有效。

+1

看看https://developer.mozilla.org/en/docs/Web/HTML/Element/link#Browser_compatibility - 看起來就是這樣吧 –

+0

@JaromandaX:我看到'?',而不是「不支持「,對於OP詢問的...... –

+0

顯然MDN不知道 - 從上面的證據可以看出,它不被支持 - 而且我**知道當假設 –

回答

2

如果通知是不可靠的,你可以輪詢看到新樣式表到達時,看到評論:

(function() { 
    // Remember how many stylesheets there are 
    var old = document.styleSheets.length; 

    // Set a timeout 
    var timeout = Date.now() + 30000; 

    // Watch for new arrivals 
    var timer = setInterval(function() { 
     if (document.styleSheets.length > old) { 
      console.log("Got it! " + document.styleSheets.length); 
      clearInterval(timer); 
     } else if (Date.now() > timeout) { 
      console.log("Give up"); 
      clearInterval(timer); 
     } 
    }, 100); 

    // Add the stylesheet link 
    var link = document.createElement('link'); 
    link.rel = "stylesheet"; 
    link.href = "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css"; 
    link.onload = function() { 
     console.log("Got it, clearing timer"); 
     clearInterval(timer); 
     // ... 
    }; 
    link.onerror = function() { 
     console.log("Got error, clearing timer"); 
     clearInterval(timer); 
     // ... 
    }; 
    document.querySelector('head').appendChild(link); 
})(); 

的優勢,這種過度使用Ajax請求是,你不需要CORS。

注:我用Date.now爲了方便上面,你需要墊片/填充工具它(或不使用)上的一些你提到的瀏覽器。墊片/填充工具很簡單:

if (!Date.now) { 
    Date.now = function() { 
     return +new Date; 
    }; 
} 
+1

謝謝,似乎對我來說很好:) –

0

幸運,https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css啓用了CORS,這樣你就可以使用XMLHttpRequest,甚至,取

使用取

fetch('https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css') 
.then(function(response) { 
    return response.text(); 
}) 
.then(function(text) { 
    var style = document.head.appendChild(document.createElement('style')); 
    style.textContent = text; 
    console.log('style loaded'); 
}).catch(function(err) { 
    console.error('style load failed with error', err); 
}); 

填充工具的獲取 - https://github.com/github/fetch你如果你需要一個提取,你可能還需要一個Promise的polyfill - https://www.promisejs.org/#browser

你可以使用XMLHtt pRequest也一樣,如果你想

var xhr = new XMLHttpRequest(); 
xhr.open('GET', 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css'); 
xhr.addEventListener('load', function() { 
    console.log('style loaded', this.responseText); 
}); 
xhr.addEventListener('error', function(e) { 
    console.error('style load failed'); 
}); 
xhr.send(); 

如果你正在寫從石器時代的瀏覽器,有一些方法可以實現同樣的事情,使用ActiveX的垃圾,並在Internet Explorer中一些奇怪的跨域黑客 - 使用它或任何

+0

*「你也可以使用XMLHttpRequest,如果你想的話」*好吧,不是在IE8或IE9上。:-) –

+0

幾年前我停止關心Windows XP - 如果你想運行XP,不要使用IE - 簡單的解決方案 –

+0

鑑於OP甚至沒有提及互聯網爆炸者,那麼你有一個牛意見:p –