如何检查CSS规则是否存在

13

我需要检查CSS规则是否存在,因为我想在未包含某些CSS文件时发出一些警告。

最好的方法是什么?

我可以通过 window.document.styleSheets.cssRules 进行筛选,但我不确定它在不同浏览器中的兼容性(另外我注意到在 Stack Overflow 中,styleSheet[0] 的对象为 null)。

我还想尽可能减少依赖。

有没有简单直接的方法呢?或者我只能创建匹配的元素并测试效果吗?

编辑:如果不行,那么检查 window.document.styleSheets 的跨浏览器问题是什么?

5个回答

9

我不知道这是否适用于您,但是如果您想要检查单个文件,则可以编写错误消息并切换样式以在该文件中隐藏它。

<span class="include_error">Error: CSS was not included!</span>

CSS 文件:

.include_error {
    display: none;
    visibility: hidden;
}

是的,这与我目前的策略类似。目前为止,我能做到的最好的就是 .css-file-loaded-marker { z-index: -98256; }$('<p>').addClass('css-file-loaded-marker').css('z-index') == -98256。我不知道跨浏览器是否真的如此,所有浏览器都支持这样的 z-index 吗?所有浏览器都会将 CSS 应用于分离的元素吗? - George Mauer
1
是的,我认为是这样的。http://www.w3schools.com/cssref/pr_pos_z-index.asp 我更喜欢我的解决方案,因为它的开销更小,即使JavaScript被禁用或jQuery无法加载也能正常工作。 - Smamatti
是的,我认为这是一个不错的解决方案,你得到了我的赞同。在我的情况下,由于我无法控制HTML(这是一个jQuery UI小部件),所以我需要从JS中获取信息。 - George Mauer

4

我使用javascript测试正确的CSS安装。

我的样式表中有一个CSS规则,将特定的ID设置为position:absolute。

#testObject {position: absolute;}

我会以编程的方式创建一个临时的div,id为指定的ID,并将其visibility属性设置为hidden。然后获取计算样式的position属性。如果它不是“absolute”,则所需的CSS没有被安装。
如果您不能在样式表中放置自己的规则,则可以识别一个或多个您认为代表样式表且不太可能改变的规则,并设计一个应该获得这些规则的临时对象,并通过测试它们的存在性来进行验证。
或者,最后,您可以尝试枚举所有外部样式表,并查找是否包含特定的文件名。
重点在于,如果您想查看外部样式表是否已包含,则必须选择有关该样式表的某些内容进行查找(文件名或其中的某些规则或引起的某些效果)。

问题在于这个解决方案需要控制CSS文件。如果你没有怎么办?例如,我想测试开发人员是否记得包含第三方小部件所需的CSS。当然,我可以选择其中的一条规则,但是非常脆弱。 - George Mauer
你需要去寻找某些东西!你可以寻找一个特定文件名的包含样式表,或者寻找特定规则的存在。选择你想要寻找的内容。你必须去寻找某些东西。我提出了一个建议,但如果你愿意,也可以寻找样式表中已经存在的特定规则。是的,如果实现发生了很多变化,它可能会有点脆弱,但你必须寻找某些东西,因此如果整个文件都可能发生变化,那么你必须接受一些探测方法在未来可能会失效的可能性。 - jfriend00
是的,我不反对寻找规则,但寻找这些规则的效果更加脆弱,因为你必须平衡“他们不太可能改变的东西”与“不太可能源于其他规则的影响”。如果您可以直接测试规则的存在,则将消除该方程式的一半。 - George Mauer
@George Mauer - 如果你想直接检查样式表,虽然在跨浏览器方面有点麻烦,但是检查自定义创建的div的效果并不更加脆弱,而且跨浏览器要简单得多。你只需使用目标id或类创建div,如果没有得到想要的效果,则所需规则必须未激活。 - jfriend00

3
以下是我得到的可行方案,类似于@Smamatti和@jfriend00的答案,但更加详细。我真的希望有一种直接测试规则的方法,但无论如何。

CSS:

.my-css-loaded-marker { 
  z-index: -98256; /*just a random number*/
}

JS:

$(function () { //Must run on jq ready or $('body') might not exist

    var dummyElement = $('<p>')
                  .hide().css({height: 0, width: 0})
                  .addClass("my-css-loaded-marker")
                  .appendTo("body");  //Works without this on firefox for some reason

    if (dummyElement.css("z-index") != -98256 && console && console.error) {
        console.error("Could not find my-app.css styles. Application requires my-app.css to be loaded in order to function properly");
    }
    dummyElement.remove();
});

该死,在某些情况下,这在Chrome上失败了。到底是怎么回事? - George Mauer
始终对我有效(请注意,我使用d3检查样式)。奇怪。有什么消息吗? - Gábor Lipták
我最终采取了不同的方法,所以最近并没有尝试做这件事,抱歉。 - George Mauer

3
我会使用类似这样的CSS选择器,从您的jQuery小部件中进行翻译。
$('link[href$="my-app.css"]')

如果你得到了一个结果,这意味着有一个链接元素,其href以"my-app.css"结尾。
接下来,使用此函数验证您依赖的元素上的特定css属性。我建议使用与您的样式相关的某些具体内容,如容器的宽度,而不是像-9999 zindex之类的任意值。
var getStyle = function(el, styleProp) {
    var x = !!el.nodeType ? el : document.getElementById(el);
    if (x.currentStyle)
        var y = x.currentStyle[styleProp];
    else if (window.getComputedStyle)
        var y = document.defaultView.getComputedStyle(x, null).getPropertyValue(styleProp);
    return y;
}

像这样

getStyle($('#stats-container')[0], "width") 

或者

getStyle("stats-container", "width")

其实是个好主意。这个线程中还没有提到,但“仅检查页面上是否存在该链接”是完全有效的方法。不过,我总是建议提供一个设置来禁止该检查,以防CSS被重命名或合并。 - George Mauer
@GeorgeMauer 如果我正在构建依赖于 CSS 的 JS 插件,我会使 JS 动态加载链接的 CSS 到页面,并在加载后运行回调函数。这样你就可以控制文件名和加载/可用时间。 - Matthew.Lothian
我们在讨论细枝末节的问题,但如果我发现一个组件没有覆盖选项就这样做,我会非常生气,因为这破坏了合并js的整个目的。 - George Mauer

0
如果你担心无法编辑其他人的样式表,你可以通过自己的样式表使用import来代理它们。
@import url('http://his-stylesheet.css');
.hideErrorMessage{ ... }

如果您只想知道代码是否尝试加载样式表,这就足够了,但如果您需要知道外部样式表是否已正确加载,则无法提供帮助。


我不明白,这怎么告诉我他的-stylesheet.css是否已经被加载?具体问题在于我有一个依赖于CSS的jQuery小部件,如果它们没有被加载,我想要控制台输出错误消息。 - George Mauer
这个想法是你需要将代码中所有对“his-StyleSheet.css”的引用改为“myProxyStylesheet.css”。正如我最初提到的那样,这在你的情况下可能并不是非常有用(因为你实际上想要检测外部样式表),但如果你认为问题可能只是忘记首先包含样式表,那么这个想法就很有用了。 - hugomg

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