[英]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幫助程序庫和資產加載程序都要求您重復媒體查詢,而不是從JS / DOM以編程方式查找它們。
所以,我一直在探索通過document.stylesheets
以編程方式訪問這些值的能力,但我不確定它們是否可訪問,並且似乎很少有文檔表明它們是。
我得到的最遠的是尋找CSSMediaRule
並使用console.dir(document.stylesheets)
來探索樣式表對象。
但是沒有引用(在document.stylesheets
)CSS中使用的實際媒體查詢規則 - 只有作為媒體查詢的結果才應用的類...我試圖以編程方式找到的是:
“屏幕和(最大寬度: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 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>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.