更改CSS链接并等待新的CSS加载完成

10
我想知道是否可能更改加载文档的样式表链接,等待新的css加载完成,然后运行适当的js代码。
感谢任何建议。

http://www.w3.org/community/webed/wiki/Dynamic_style_-_manipulating_CSS_with_JavaScript#Accessing_style_sheets - Ana
6个回答

5

html:

<link id="mystylesheet" href="/path/to/css.css" />

代码:

$("#mystylesheet").load(function(){
  //Your javascript
}).attr("href", "/new/path/to/css.css");

这将替换您当前的CSS,并在新的CSS文件被获取后执行.load()处理程序中的任何代码。

FYI,这对移动设备不起作用...请参见下面我修订后适用于更广泛浏览器范围的答案。 - Chad Brown
1
@ahren 这个解决方案会等待 CSS 应用吗?如果不会,有什么方法可以做到这一点吗? - Kragalon

3

@ahren几乎正确。然而,通过在链接元素上动态更改href并在css文件加载完成时使用回调,在大多数移动设备上似乎无法工作。

相反,尝试使用load直接将样式注入到样式元素中,这种方法被大多数现代浏览器包括移动设备支持。

更新以包括对IE 8-的支持;注意,这需要您向css中注入一个虚拟规则来验证css何时已加载(在此示例中使用body {ready:true;})。

css

body {ready:true;}
...

html

<style id="your-style-element"></style>

javascript

if (document.createStyleSheet) {

    //Wait for style to be loaded
    var wait = setInterval(function(){
      //Check for the style to be applied to the body
      if($('body').css('ready') === 'true') {
        clearInterval(wait);

        //CSS ready
      }
    }, 300);

    document.createStyleSheet(url);
} else {
    //Dynamically load the css for this doc
    $("#your-style-element").load(url,function(){

       //CSS ready
    });
}

请注意,CSS 中引用的任何 URL 都是相对于页面而不是 CSS 文件位置的。 - Chad Brown
1
.load()方法在CSS规则应用后触发吗?如果不是,有没有可行的方法来实现这一点? - Kragalon
@Kragalon 我敢打赌你可以每帧检查一次特定的样式属性(你知道存在于远程样式表中),直到期望的值生效为止(使用requestAnimationFrame在循环中)。 :) - aleclarson

0

这是我写的一个要点,只用了47行代码就完美运行:

https://gist.github.com/aleclarson/ac6456c75edae9fe9d9b6938142a065b

它使用requestAnimationFrame在每一帧检查document.styleSheets,直到每个给定的URL片段都被加载。
例子:
const styles = require('./styles')
const promise = styles.onLoad('foo.css', 'bar.css')
promise.then(() => console.log('Styles loaded!'))

纯JavaScript,太棒了!


0

你可以试试我为这种情况编写的插件

关于jQuery.load()方法,我不确定它是否支持跨浏览器。据我所知,只有IE支持链接元素上的onload=""事件。


0

0

TeaCoder在https://dev59.com/qFsV5IYBdhLWcg3w6iV8#35644406上对这个问题有一个很好的答案。

基本上使用元素的onload方法,并将您想要在样式加载后发生的逻辑放在那里。

这是一种使用内置DOM功能的不错方式,但回调语法有点笨拙。以下是我使用Promise的方法:

const createOnLoadPromise = (htmlElement) =>
  new Promise((resolve) => {
    htmlElement.onload = resolve;
  });
const link1 = document.head.appendChild(createStyleLink(href1));
const link2 = document.head.appendChild(createStyleLink(href2));
await Promise.all([
  createOnLoadPromise(link1),
  createOnLoadPromise(link2),
]);
// do whatever you need to do after the await

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接