2015-11-16 250 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 –