[英]Accessing CSS media query rules via JavaScript/DOM
I've been using a number of libraries (including my own) to dynamically load assets based upon media queries I've outlined in CSS files. 我一直在使用一些库(包括我自己的)来根据我在CSS文件中概述的媒体查询来动态加载资源。 For example:
例如:
In CSS: 在CSS中:
@media screen and (max-width: 480px) {
.foo {
display: none;
}
}
And using an asset loader; 并使用资产加载器; require.js , modernizr.js etc or using
window.matchMedia
and associated addListener()
functions: require.js , modernizr.js等或使用
window.matchMedia
和相关的addListener()
函数:
if (function("screen and (max-width: 480px)")){
// Load several files
load(['mobile.js','mobile.css']);
}
Declaring them twice is awkward/silly and as far as I can find, all JS helper libraries and asset loaders require you to repeat the media queries rather than locating them programmatically from JS/DOM. 将它们声明两次是笨拙/愚蠢的,据我所知,所有JS帮助程序库和资产加载程序都要求您重复媒体查询,而不是从JS / DOM以编程方式查找它们。
So, I've been exploring the ability to access the values programmatically via document.stylesheets
, but I'm not sure if they're accessible and there seems very little documentation to suggest they are. 所以,我一直在探索通过
document.stylesheets
以编程方式访问这些值的能力,但我不确定它们是否可访问,并且似乎很少有文档表明它们是。
The furthest I've got is looking for CSSMediaRule
and using console.dir(document.stylesheets)
amongst others to explore the stylesheet object. 我得到的最远的是寻找
CSSMediaRule
并使用console.dir(document.stylesheets)
来探索样式表对象。
But no references are made (within document.stylesheets
) to the actual media query rules used in CSS - only the classes to be applied as a result of the media queries... What I'm trying to locate, programmatically, is: 但是没有引用(在
document.stylesheets
)CSS中使用的实际媒体查询规则 - 只有作为媒体查询的结果才应用的类...我试图以编程方式找到的是:
"screen and (max-width: 480px)"
“屏幕和(最大宽度:480px)”
Is there any way of accessing such CSS Media query rules via JavaScript/DOM? 有没有办法通过JavaScript / DOM访问这样的CSS媒体查询规则 ?
For get rules use cross browser variant: 对于get规则,请使用跨浏览器变体:
var styleSheet = document.styleSheets[0];
var rules = styleSheet.cssRules || styleSheet.rules; // IE <= 8 use "rules" property
For detect CSSMediaRule object in rules list use (not work in IE <= 8, because "CSSMediaRule" class available only in IE >= 9): 对于在规则列表中使用检测CSSMediaRule对象(不在IE <= 8中工作,因为“CSSMediaRule”类仅在IE> = 9中可用):
var i = 0;
if (rules[i].type == 4)
{
// Do something
}
Some functions for get styles from current DOM (not works in IE <= 8): 从当前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;
}
Functions usage example: 功能用法示例:
<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>
Here is a JS Fiddle for it: https://jsfiddle.net/luisperezphd/hyentcqc/ 这是一个JS小提琴: https : //jsfiddle.net/luisperezphd/hyentcqc/
This is how I do it: 我是这样做的:
In css create classes to expose or hide content at various breakpoints. 在css中创建类以在各个断点处公开或隐藏内容。 This is a handy utility anyway.
无论如何,这是一个方便的实用程序。 These are already available in Twitter Bootstrap for example.
例如,这些已经在Twitter Bootstrap中提供。
<style type="text/css">
.visible-sm, .visible-md, .visible-lg{
display:none;
}
@media (max-width: 480px) {
.visible-sm{
display: block;
}
}
@media (min-width: 481px) and (max-width: 960px) {
.visible-md{
display: block;
}
}
@media (min-width: 961px) {
.visible-lg{
display: block;
}
}
</style>
In all your documents add empty spans with these classes. 在所有文档中添加这些类的空跨度。 They won't show up on the page if you keep the spans inline.
如果您保持内联的跨度,它们将不会显示在页面上。
<span id="media_test">
<span class="visible-sm"></span>
<span class="visible-md"></span>
<span class="visible-lg"></span>
</span>
Add this short jquery extension to your script file. 将此简短的jquery扩展添加到脚本文件中。 This sets a new class in the body tag that matches the current media query.
这将在body标记中设置一个与当前媒体查询匹配的新类。
(function ($) {
$.fn.media_size = function () {
//the default port size
var size = 'lg';
//the sizes used in the css
var sizes = ['sm','md','lg'];
//loop over to find which is not hidden
for (var i = sizes.length - 1; i >= 0; i--) {
if($('#media_test .visible-'+sizes[i]).css("display").indexOf('none') == -1){
size = sizes[i];
break;
};
};
//add a new class to the body tag
$('body').removeClass(sizes.join(' ')).addClass(size);
}
}(jQuery));
$(document).media_size();
Now you have an automatic integration with your css media queries Modernizr style. 现在,您可以自动集成您的css媒体查询Modernizr样式。
You can write javascript (jquery) that is conditional on based on your media queries: 您可以根据媒体查询编写有条件的javascript(jquery):
<a href="#">how big is this viewport?</a>
<script type="text/javascript">
$('.sm a').click(function(e){ alert('Media queries say I\'m a small viewport');});
$('.lg a').click(function(e){ alert('Media queries say I\'m a large viewport');});
</script>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.