admin管理员组文章数量:1201982
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. For example:
In 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:
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.
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.
The furthest I've got is looking for CSSMediaRule
and using console.dir(document.stylesheets)
amongst others to explore the stylesheet object.
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:
"screen and (max-width: 480px)"
Is there any way of accessing such 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. For example:
In 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:
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.
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.
The furthest I've got is looking for CSSMediaRule
and using console.dir(document.stylesheets)
amongst others to explore the stylesheet object.
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:
"screen and (max-width: 480px)"
Is there any way of accessing such CSS Media query rules via JavaScript/DOM?
Share Improve this question edited Jun 10, 2014 at 13:09 user2428118 8,1044 gold badges46 silver badges73 bronze badges asked Mar 29, 2013 at 1:46 nickharnickhar 20.8k12 gold badges63 silver badges77 bronze badges 4- 2 Oops, wrong link, here's the article I was looking for at coderwall – steveax Commented Mar 29, 2013 at 1:59
- 2 Good question. For my purposes, I've always checked if specific elements were visible or not, as my JavaScript interaction would apply to those elements. There should be a better, more general solution however. – Brad Commented Mar 29, 2013 at 2:08
- Hey, check it. It can be a solution. github.com/nathansmith/adapt/blob/master/assets/js/adapt.js – user2193789 Commented Mar 29, 2013 at 2:36
- @steveax That's not what I was looking directly for, but, it's a fantastic alternative/leftfield approach - which solves my problem Thanks! – nickhar Commented Apr 14, 2013 at 21:12
2 Answers
Reset to default 14For get rules use cross browser variant:
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):
var i = 0;
if (rules[i].type == 4)
{
// Do something
}
Some functions for get styles from current DOM (not works in 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/
This is how I do it:
In css create classes to expose or hide content at various breakpoints. This is a handy utility anyway. These are already available in Twitter Bootstrap for example.
<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. This sets a new class in the body tag that matches the current media query.
(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.
You can write javascript (jquery) that is conditional on based on your media queries:
<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>
本文标签: Accessing CSS media query rules via JavaScriptDOMStack Overflow
版权声明:本文标题:Accessing CSS media query rules via JavaScriptDOM - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1738576637a2100917.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论