通过JavaScript/DOM访问CSS媒体查询规则
Accessing CSS media query rules via JavaScript/DOM
我一直在使用一些库(包括我自己的库)来根据我在CSS文件中概述的媒体查询动态加载资源。例如:
在CSS: @media screen and (max-width: 480px) {
.foo {
display: none;
}
}
和使用资源加载器;require.js, modernizr.js等或使用window.matchMedia
和相关的addListener()
函数:
if (function("screen and (max-width: 480px)")){
// Load several files
load(['mobile.js','mobile.css']);
}
声明它们两次是尴尬/愚蠢的,据我所知,所有JS helper库和资产加载器都要求你重复媒体查询,而不是从JS/DOM以编程方式定位它们。
所以,我一直在探索通过document.stylesheets
以编程方式访问值的能力,但我不确定它们是否可以访问,并且似乎很少有文档表明它们是。
我得到的最远的是寻找CSSMediaRule
并使用console.dir(document.stylesheets)
在其他中探索样式表对象。
但是没有引用(在document.stylesheets
中)在CSS中使用的实际媒体查询规则-只有作为媒体查询结果应用的类…我想找到的,程序化,是:
"screen and (max-width: 480px)"
是否有办法通过JavaScript/DOM访问这样的CSS媒体查询规则 ?
对于get规则使用跨浏览器变体:
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提琴:https://jsfiddle.net/luisperezphd/hyentcqc/
我是这样做的:
在css中创建类以在不同的断点处显示或隐藏内容。无论如何,这是一个方便的实用程序。例如,这些已经在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>
在所有文档中使用这些类添加空跨。如果你保持span内嵌,它们就不会显示在页面上。
<span id="media_test">
<span class="visible-sm"></span>
<span class="visible-md"></span>
<span class="visible-lg"></span>
</span>
添加这个简短的jquery扩展到你的脚本文件。这将在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();
现在你有一个自动集成与你的css媒体查询Modernizr风格。
你可以根据你的媒体查询来编写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>
- 内部分区字体大小获胜'调整浏览器窗口大小时不会随媒体查询而更改
- 触发媒体查询断点时刷新页面
- 媒体查询/matchMedia上的脚本
- 使用按钮和媒体查询切换显示状态
- 加载dom后禁用媒体查询
- 将语句与jquery相结合,并使用媒体查询来实现返回页首按钮
- 媒体查询与Javascript相结合
- 访问CSS媒体查询中的屏幕宽度和高度
- 使用媒体查询和angular更改移动设备中ng href的值
- 媒体查询和调整现成的网站
- 有没有一种方法可以修改在使用javascript的媒体功能的媒体查询下创建的样式
- 如何使用EnquireJS使AngularJS范围变量依赖于媒体查询
- @媒体查询在桌面浏览器中有效,而在移动浏览器中无效
- css媒体查询请求后刷新jQuery插件
- jQuery.thoggle()和媒体查询
- 使用媒体查询设置背景图像的不透明度
- 媒体查询:如何仅定位平板电脑
- 如何将垂直选项卡式内容面板更改为具有媒体查询和 jquery 的响应式可折叠面板
- 根据浏览器屏幕大小和媒体查询执行 php 代码
- CSS 媒体查询 - 最小设备宽度和最大设备宽度