动态加载 css 样式表并等待它加载
Dynamically load css stylesheet and wait for it to load
我有一个脚本可以检测按钮点击,它会将 CSS 样式表附加到 jQuery 的“头部”,如下所示:
const link = "<link class='listcss' rel='stylesheet' href='http://....list.css'>";
$("head").append(link);
然后我需要根据 css 宽度和高度属性做一些计算:
function CSSDone(){
if($(window).width()>640){
$(".grid-item").css({"height":$(".grid-item").width()*0.2});
$(".grid_item_img").css({"height":$(".grid-item").width()*0.2});
console.log("a");
}else{
$(".grid-item").css({"height":$(".grid-item").width()*0.33});
$(".grid_item_img").css({"height":$(".grid-item").width()*0.33});
console.log("b");
}
}
CSSDone();
但是,如果我启动 CSSDone();添加样式表后,计算发生在 css 加载之前。
我疯狂地搜索了网络,但我尝试的一切都不起作用:
我尝试了这些选项:
无效:
link.onload = 函数 () {
CSS完成();
}
无效:
if (link.addEventListener) {
link.addEventListener('load', function() {
CSSDone();
}, false);
}
无效:
link.onreadystatechange = function() {
var state = link.readyState;
if (state === 'loaded' || state === 'complete') {
link.onreadystatechange = null;
CSSDone();
}
};
无效:
$(window).load(function () {
CSSDone();
});
无效:
$(window).bind("load", function() {
CSSDone();
});
相信我。什么都没用......
**一个解决方法:**
我将 css 加载到 DOM 中,然后立即使用 jQuery 将其删除。这样,稍后将 link 添加到头部时就足够快了。
您需要在头部插入一个 link
节点,然后将 onload
事件附加到该节点。在您的代码中 link 是一个字符串。请参阅下面的示例代码,了解如何实现您想要的。
var link = document.createElement('link');
link.setAttribute("rel", "stylesheet");
link.setAttribute("type", "text/css");
link.onload = CSSDone;
link.setAttribute("href", 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css');
document.getElementsByTagName("head")[0].appendChild(link);
检查jsfiddle。
我相信你可以试试这个.. 在 $("head").append(link)
的回调中包含 CSSDone()
代码
$(document).ready(function(){
$('.btn').on('click', function(){
link = "<link class='listcss' rel='stylesheet' href='/list.css'>";
$("head").append(link, function(){
if($(window).width()>640){
$(".grid-item").css({"height":$(".grid-item").width()*0.2});
$(".grid_item_img").css({"height":$(".grid-item").width()*0.2});
console.log("a");
}else{
$(".grid-item").css({"height":$(".grid-item").width()*0.33});
$(".grid_item_img").css({"height":$(".grid-item").width()*0.33});
console.log("b");
}
}); // append link
}); // button click
}); // document ready
使用jQuery:
var head = $('head');
var link = $('<link>')
.attr('rel', 'stylesheet')
.attr('type', 'text/css')
.attr('href', url)
.on('load', callback)
.on('error', error)
.appendTo(head);
在动态插入样式 sheet link 并依赖于这些计算时绕过竞争条件:
function downloadCSS(url) {
function insertCss(code) {
var style = document.createElement('style');
style.type = 'text/css';
style.innerHTML = code;
document.querySelector("head").appendChild(style);
}
return new Promise(async (resolve, reject) => {
try {
let src = await axios.get(url);
insertCss(src.data);
} catch (e) {
return reject(e);
}
requestAnimationFrame(function () {
resolve();
});
});
}
(async function setup() {
try {
await downloadCSS('https://myapp.com/style.css');
} catch (e) {
return reject(e);
}
//rest of code
})();
我将 axios 库用于 HTTP 请求,但您可以使用任何您喜欢的东西。
想法是等待下载CSS 承诺下载 CSS 的 url,然后插入代码作为与 link 相对的样式元素,然后在下一帧解析承诺并从那里继续。
我有一个脚本可以检测按钮点击,它会将 CSS 样式表附加到 jQuery 的“头部”,如下所示:
const link = "<link class='listcss' rel='stylesheet' href='http://....list.css'>";
$("head").append(link);
然后我需要根据 css 宽度和高度属性做一些计算:
function CSSDone(){
if($(window).width()>640){
$(".grid-item").css({"height":$(".grid-item").width()*0.2});
$(".grid_item_img").css({"height":$(".grid-item").width()*0.2});
console.log("a");
}else{
$(".grid-item").css({"height":$(".grid-item").width()*0.33});
$(".grid_item_img").css({"height":$(".grid-item").width()*0.33});
console.log("b");
}
}
CSSDone();
但是,如果我启动 CSSDone();添加样式表后,计算发生在 css 加载之前。 我疯狂地搜索了网络,但我尝试的一切都不起作用:
我尝试了这些选项:
无效:
link.onload = 函数 () { CSS完成(); }
无效:
if (link.addEventListener) { link.addEventListener('load', function() { CSSDone(); }, false); }
无效:
link.onreadystatechange = function() { var state = link.readyState; if (state === 'loaded' || state === 'complete') { link.onreadystatechange = null; CSSDone(); } };
无效:
$(window).load(function () { CSSDone(); });
无效:
$(window).bind("load", function() { CSSDone(); });
相信我。什么都没用......
**一个解决方法:**
我将 css 加载到 DOM 中,然后立即使用 jQuery 将其删除。这样,稍后将 link 添加到头部时就足够快了。
您需要在头部插入一个 link
节点,然后将 onload
事件附加到该节点。在您的代码中 link 是一个字符串。请参阅下面的示例代码,了解如何实现您想要的。
var link = document.createElement('link');
link.setAttribute("rel", "stylesheet");
link.setAttribute("type", "text/css");
link.onload = CSSDone;
link.setAttribute("href", 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css');
document.getElementsByTagName("head")[0].appendChild(link);
检查jsfiddle。
我相信你可以试试这个.. 在 $("head").append(link)
的回调中包含 CSSDone()
代码
$(document).ready(function(){
$('.btn').on('click', function(){
link = "<link class='listcss' rel='stylesheet' href='/list.css'>";
$("head").append(link, function(){
if($(window).width()>640){
$(".grid-item").css({"height":$(".grid-item").width()*0.2});
$(".grid_item_img").css({"height":$(".grid-item").width()*0.2});
console.log("a");
}else{
$(".grid-item").css({"height":$(".grid-item").width()*0.33});
$(".grid_item_img").css({"height":$(".grid-item").width()*0.33});
console.log("b");
}
}); // append link
}); // button click
}); // document ready
使用jQuery:
var head = $('head');
var link = $('<link>')
.attr('rel', 'stylesheet')
.attr('type', 'text/css')
.attr('href', url)
.on('load', callback)
.on('error', error)
.appendTo(head);
在动态插入样式 sheet link 并依赖于这些计算时绕过竞争条件:
function downloadCSS(url) {
function insertCss(code) {
var style = document.createElement('style');
style.type = 'text/css';
style.innerHTML = code;
document.querySelector("head").appendChild(style);
}
return new Promise(async (resolve, reject) => {
try {
let src = await axios.get(url);
insertCss(src.data);
} catch (e) {
return reject(e);
}
requestAnimationFrame(function () {
resolve();
});
});
}
(async function setup() {
try {
await downloadCSS('https://myapp.com/style.css');
} catch (e) {
return reject(e);
}
//rest of code
})();
我将 axios 库用于 HTTP 请求,但您可以使用任何您喜欢的东西。
想法是等待下载CSS 承诺下载 CSS 的 url,然后插入代码作为与 link 相对的样式元素,然后在下一帧解析承诺并从那里继续。