我一直在使用许多库(包括我自己的库)来根据我在 CSS 文件中概述的媒体查询动态加载 Assets 。例如:
在 CSS 中:
@media screen and (max-width: 480px) {
.foo {
display: none;
}
}
并且使用 Assets 加载器; require.js , modernizr.js等或使用 window.matchMedia
和相关的 addListener()
函数:
if (function("screen and (max-width: 480px)")){
// Load several files
load(['mobile.js','mobile.css']);
}
声明它们两次是笨拙/愚蠢的,据我所知,所有 JS 帮助程序库和 Assets 加载器都要求您重复媒体查询,而不是从 JS/DOM 以编程方式定位它们。
所以,我一直在探索通过 document.stylesheets
以编程方式访问这些值的能力,但我不确定它们是否可以访问,而且似乎很少有文档表明它们是.
我得到的最远的是寻找 CSSMediaRule
并使用 console.dir(document.stylesheets)
等来探索样式表对象。
但没有引用(在 document.stylesheets
中)CSS 中使用的实际媒体查询规则 - 只有作为媒体查询结果应用的类......我是什么我试图以编程方式定位是:
"screen and (max-width: 480px)"
有没有办法通过 JavaScript/DOM 访问此类 CSS 媒体查询规则?
最佳答案
获取规则使用跨浏览器变体:
var styleSheet = document.styleSheets[0];
var rules = styleSheet.cssRules || styleSheet.rules; // IE <= 8 use "rules" property
用于检测规则列表中的 CSSMediaRule 对象(在 IE <= 8 中不起作用,因为“CSSMediaRule”类仅在 IE >= 9 中可用):
var i = 0;
if (rules[i].type == 4)
{
// Do something
}
从当前 DOM 中获取样式的一些函数(在 IE <= 8 中不起作用):
function getCssRulesFromDocumentStyleSheets(media)
{
var resultCssRules = '';
for (var i = 0; i < document.styleSheets.length; i++)
{
var styleSheet = document.styleSheets[i];
if (isRuleFromMedia(styleSheet, media))
resultCssRules += getCssRulesFromRuleList(styleSheet.cssRules || styleSheet.rules, media);
}
return resultCssRules;
}
function getCssRulesFromRuleList(rules, media)
{
var resultCssRules = '';
for (var i = 0; i < rules.length; i++)
{
var rule = rules[i];
if (rule.type == 1) // CSSStyleRule
{
resultCssRules += rule.cssText + "\r\n";
}
else if (rule.type == 3) // CSSImportRule
{
if (isRuleFromMedia(rule, media))
resultCssRules += getCssRulesFromRuleList(rule.styleSheet.cssRules || rule.styleSheet.rules, media);
}
else if (rule.type == 4) // CSSMediaRule
{
if (isRuleFromMedia(rule, media))
resultCssRules += getCssRulesFromRuleList(rule.cssRules || rule.rules, media);
}
}
return resultCssRules;
}
function isRuleFromMedia(ruleOrStyleSheet, media)
{
while (ruleOrStyleSheet)
{
var mediaList = ruleOrStyleSheet.media;
if (mediaList)
{
if (!isMediaListContainsValue(mediaList, media) && !isMediaListContainsValue(mediaList, 'all') && mediaList.length > 0)
return false;
}
ruleOrStyleSheet = ruleOrStyleSheet.ownerRule || ruleOrStyleSheet.parentRule || ruleOrStyleSheet.parentStyleSheet;
}
return true;
}
function isMediaListContainsValue(mediaList, media)
{
media = String(media).toLowerCase();
for (var i = 0; i < mediaList.length; i++)
{
// Access to mediaList by "[index]" notation now work in IE (tested in versions 7, 8, 9)
if (String(mediaList.item(i)).toLowerCase() == media)
return true;
}
return false;
}
函数使用示例:
<style type="text/css">
@media screen and (max-width: 480px) {
p { margin: 10px; }
}
@media screen and (max-width: 500px) {
p { margin: 15px; }
}
@media print {
p { margin: 20px; }
}
</style>
<!-- ... -->
<script type="text/javascript">
alert(getCssRulesFromDocumentStyleSheets('print'));
alert(getCssRulesFromDocumentStyleSheets('screen and (max-width: 480px)'));
// For IE (no space after colon), you can add fix to "isMediaListContainsValue" function
alert(getCssRulesFromDocumentStyleSheets('screen and (max-width:480px)'));
</script>
这是它的 JS Fiddle:https://jsfiddle.net/luisperezphd/hyentcqc/
关于javascript - 通过 JavaScript/DOM 访问 CSS 媒体查询规则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15696124/