如何判断CSS是否已经加载?

问题描述 投票:0回答:6

如何断言页面的 CSS 已在 Watin 2.1 中成功加载并应用其样式?

css watin
6个回答
32
投票

在做了一些研究并写下我的答案之后,我偶然发现了这个链接,它解释了你需要了解的有关CSS、何时加载以及如何检查它的所有信息。

提供的链接解释得非常好,事实上,我添加了一些引用以供将来参考。
如果你好奇,我的答案是#2 和#4 的变体。

样式表何时真正加载?

...

抛开这些,让我们看看这里有什么。

// my callback function 
// which relies on CSS being loaded function
CSSDone() {
    alert('zOMG, CSS is done');
};

// load me some stylesheet 
var url = "http://tools.w3clubs.com/pagr/1.sleep-1.css",
    head = document.getElementsByTagName('head')[0],
    link = document.createElement('link');

link.type = "text/css"; 
link.rel = "stylesheet";
link.href = url;

// MAGIC 
// call CSSDone() when CSS arrives
head.appendChild(link);

神奇部分的选项,从简单易用到荒谬排序

  1. 听 link.onload
  2. 监听 link.addEventListener('load')
  3. 听 link.onreadystatechange
  4. setTimeout 并检查 document.styleSheets 中的更改
  5. setTimeout 并检查您创建但使用新 CSS 进行样式设置的特定元素的样式变化

第五个选项太疯狂了,它假设你可以控制 CSS 的内容,所以忘记它吧。另外,它会在超时时检查当前样式,这意味着它将刷新回流队列,并且可能会很慢。 CSS 到达的速度越慢,回流就越多。所以,真的,忘记它吧。

那么实施这个魔法怎么样?

// MAGIC 

// #1   
link.onload = function () {
    CSSDone('onload listener');
};   

// #2   
if (link.addEventListener) {
    link.addEventListener('load', function() {
        CSSDone("DOM's load event");
    }, false);   
};   

// #3   
link.onreadystatechange = function() {
    var state = link.readyState;
    if (state === 'loaded' || state === 'complete') {
        link.onreadystatechange = null;
        CSSDone("onreadystatechange");
    }   
};

// #4   
var cssnum = document.styleSheets.length;
var ti = setInterval(function() {
    if (document.styleSheets.length > cssnum) {
        // needs more work when you load a bunch of CSS files quickly
        // e.g. loop from cssnum to the new length, looking
        // for the document.styleSheets[n].href === url
        // ...

        // FF changes the length prematurely :(
        CSSDone('listening to styleSheets.length change');
        clearInterval(ti);
    }   
}, 10);

// MAGIC ends

13
投票

@ShadowScripter 所写的文章已更新。据称,新方法适用于所有浏览器,包括 FF。

var style = document.createElement('style');
style.textContent = '@import "' + url + '"';

var fi = setInterval(function() {
  try {
    style.sheet.cssRules; // <--- MAGIC: only populated when file is loaded
    CSSDone('listening to @import-ed cssRules');
    clearInterval(fi);
  } catch (e){}
}, 10);  

document.getElementsByTagName('head')[0].appendChild(style);

2
投票

页面加载后,您可以验证某些元素的样式,如下所示:

var style = browser.Div(Find.ByClass("class")).Style;
Assert.That(Style.Display, Is.StringContaining("none"));
Assert.That(Style.FontSize, Is.EqualTo("10px"));

等等...


1
投票

由于浏览器兼容性可能会有所不同,并且未来新的浏览器标准可能会发生变化,因此我建议将 onload 侦听器与将 CSS 添加到样式表相结合,以便您可以侦听 HTML 元素 z-index 何时发生变化(如果您使用的是单一样式表。否则,请使用下面的函数,并为每种样式添加一个新的元标记。

将以下内容添加到您正在加载的 CSS 文件中:

#*(insert a unique id for he current link tag)* {
    z-index: 0
}

将以下内容添加到您的脚本中:

function whencsslinkloads(csslink, whenload ){
    var intervalID = setInterval(
        function(){
            if (getComputedStyle(csslink).zIndex !== '0') return;
            clearInterval(intervalID);
            csslink.onload = null;
            whenload();
        },
        125 // check for if it has loaded 8 times a second
    );
    csslink.onload = function(){
        clearInterval(intervalID);
        csslink.onload = null;
        whenload();
    }
}

示例

index.html

<!doctype html>
<html>
    <head>
        <link rel=stylesheet id="EpicStyleID" href="the_style.css" />
        <script async href="script.js"></script>
    </head>
    <body>
        CSS Loaded: <span id=result>no</span>
    </body>
</html>

script.js

function whencsslinkloads(csslink, whenload ){
    var intervalID = setInterval(
        function(){
            if (getComputedStyle(csslink).zIndex !== '0') return;
            clearInterval(intervalID);
            csslink.onload = null;
            whenload();
        },
        125 // check for if it has loaded 8 times a second
    );
    csslink.onload = function(){
        clearInterval(intervalID);
        csslink.onload = null;
        whenload();
    }
}
/*************************************/
whencsslinkloads(
    document.getElementById('EpicStyleID'),
    function(){
        document.getElementById('result').innerHTML = '<font color=green></font>'
    }
)

the_style.css

#EpicStyleID {
    z-index: 0
}

请不要让您的脚本同步加载(没有

async
属性),这样您就可以捕获链接的 onload 事件。还有更好的方法,就像上面的方法。


1
投票

只需检查 CSS 变量是否存在

var blnCSSLoaded = false;
var iCSSLoad = setInterval(function() {
    var bodyStyles = window.getComputedStyle(document.body);
    var fooBar = bodyStyles.getPropertyValue('--blnMyCSSInit');
    if(fooBar) {
        clearInterval(iCSSLoad);
        blnCSSLoaded = true;
    }
}, 200);

你必须像这样在 CSS 中定义变量

:root {
  --blnMyCSSInit: #0077bf;
}

0
投票

这也应该有效:

(() => {
  const url = "https://www.w3schools.com/plus/plans/main.css";
  const style = document.createElement('style');
  style.textContent = `@import url(${url});`;
  console.log(style.sheet == null);
  style.onload = () => console.log(style.sheet != null);
  document.head.append(style); // start loading the css file!
})();

© www.soinside.com 2019 - 2024. All rights reserved.