这是Prime混合领域。首先我们将定义一个帮助程序来管理样式表。
我们需要一个函数来加载样式表,并返回其成功的承诺。实际上,要检测样式表的加载状态是非常疯狂的...
function loadStyleSheet(url){
var sheet = document.createElement('link');
sheet.rel = 'stylesheet';
sheet.href = url;
sheet.type = 'text/css';
document.head.appendChild(sheet);
var _timer;
return new Promise(function(resolve){
sheet.onload = resolve;
sheet.addEventListener('load', resolve);
sheet.onreadystatechange = function(){
if (sheet.readyState === 'loaded' || sheet.readyState === 'complete') {
resolve();
}
};
_timer = setInterval(function(){
try {
for (var i=0; i<document.styleSheets.length; i++) {
if (document.styleSheets[i].href === sheet.href) resolve();
} catch(e) { }
}
}, 250);
})
.then(function(){ clearInterval(_timer); return link; });
}
哇,我原本只是想在上面放一个onload事件,但不行。这段代码未经测试,请在发现任何错误时更新它——它是从几篇博客文章编译而来的。
其余部分相当简单:
- 允许加载样式表
- 在可用时更新状态(以防止FOUC)
- 在组件卸载时卸载任何已加载的样式表
- 处理所有异步好处
var mixin = {
componentWillMount: function(){
this._stylesheetPromises = [];
},
loadStyleSheet: function(name, url){
this._stylesheetPromises.push(loadStyleSheet(url))
.then(function(link){
var update = {};
update[name] = true;
this.setState(update);
}.bind(this));
},
componentWillUnmount: function(){
this._stylesheetPromises.forEach(function(p){
p.then(function(link){
if (link.parentNode) link.parentNode.removeChild(link);
});
});
}
};
再次提醒,此处未经测试,请如有问题及时更新。
现在我们已经拥有了该组件。
React.createClass({
getInitialState: function(){
return {foo: false};
},
componentDidMount: function(){
this.loadStyleSheet('foo', '/css/views/foo.css');
},
render: function(){
if (!this.state.foo) {
return <div />
}
}
});
唯一需要完成的任务是在尝试加载样式表之前检查它是否已经存在。希望这能让您走上正确的道路。
"%PUBLIC_URL%/stylesheet_name.css"
还是其他的方式? - Tur1ngpublic
文件夹中的样式表,应使用PUBLIC_URL
环境变量,如下所示:<link rel='stylesheet' type='text/css' href={ process.env.PUBLIC_URL + '/foo.css' }/>
- Andy<head>
元素中。 - senornestor