javascript - 通过 JavaScript/DOM 访问 CSS 媒体查询规则

标签 javascript css dom media-queries

我一直在使用许多库(包括我自己的库)来根据我在 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/

相关文章:

javascript 错误时事通讯在响应式 View 中不起作用

javascript - DIV 元素的 Border-Radius 在 IE8 中不起作用

javascript - document.getElementById 不会设置变量

javascript - uglify 无法在 gulp 中运行 js 文件

javascript - 在鼠标松开之前在下部 Canvas 上渲染画笔描边

javascript - 选中复选框并触发更改事件javascript

javascript - jquery/javascript 读取选择框 css/class

javascript - 试图在javascript中打开多个窗口

jquery - 如何将 After Effects 动画嵌入我的网站?

javascript - sheet.cssRules 在内页上抛出错误但在主页上工作正常