【问题标题】:Javascript: Removing media query from external css fileJavascript:从外部 css 文件中删除媒体查询
【发布时间】:2014-11-22 02:44:49
【问题描述】:

如何删除从外部 css 文件 (<link rel="stylesheet" type="text/css" href="XXXX.css" media="screen">) 加载的媒体查询?请注意,我不能禁用整个链接标记,因为该媒体查询中包含其他重要样式:

body{...}
.container{...}
...
@media(min-width:XXXpx) {
....
}
...

谢谢!

【问题讨论】:

    标签: javascript html css media-queries


    【解决方案1】:

    我强烈推荐纯 CSS 解决这个问题,比如定义一个新的样式表覆盖你不想要的规则。

    #selector {
        color: #000;
    }
    
    .some-classs-you-want-to-reserve {/*..*/}
    
    @media only screen and (min-width: 600px) {
        /* unwanted */
        #selector {
            display: none;
        }
    }
    

    例如,如果您想在 @media only screen and (min-width: 600px) 中屏蔽规则,只需添加一个新样式表,将它们覆盖为默认值:

    @media only screen and (min-width: 600px) {
        /* unwanted */
        #selector {
            display: block;
        }
    }
    

    如果你坚持使用Javascript,你可以通过迭代document.styleSheets来访问和修改css规则。

    这是 StyleSheetList 的一个实例,一个类似数组的对象。它的每一项都代表一个外部或内联 CSS 样式表。包括媒体查询在内的所有规则都可以在其中找到。

    一个简短的树结构:

    - document.styleSheets
       |- CSSStyleSheet
           |- cssRules
           |- media
    

    下面是一个示例,展示了如何删除 @media only screen and (min-width: 600px) 块中定义的所有规则:

    function removeRule() {
        if(typeof window.CSSMediaRule !== "function") 
            return false; //Your browser doesn't support media query feature
    
        var s = document.styleSheets, r,
            i, j, k;
    
        if(!s) return false; //no style sheets found
    
        // walk throuth css sheets
        for(i=0; i<s.length; i++) {
            // get all rules
            r = s[i].cssRules; 
            if(!r) continue;
    
            for(j=0; j<r.length; j++) {
                //If there's a rule for media query
                if(r[j] instanceof CSSMediaRule &&
                        r[j].media.mediaText == "only screen and (min-width: 600px)") {
                    for(k=0; k<r[j].cssRules.length; k++) {
                        // remove all rules of it
                        r[j].deleteRule(r[j].cssRules[k]);
                    }
                    return true;
                }
            }
        }
    }
    removeRule();
    

    或现场小提琴:http://jsfiddle.net/e4h41qm2/

    【讨论】:

      【解决方案2】:

      事实是,如果您删除一个媒体查询,则会激活另一个媒体查询。所以你必须做一个循环,直到没有找到媒体查询:

      function removeRule() {
          if (typeof window.CSSMediaRule !== 'function') {
              return false;
          }
          var styleSheets = document.styleSheets;
          var number = 0;
      
          if (!styleSheets) {
              return false;
          }
      
          for (i = 0; i < styleSheets.length; i++) {
              var styleSheet = styleSheets[i];
              var rules = styleSheet.cssRules;
              if (!rules) {
                  continue;
              }
              for (var j = 0; j < rules.length; j++) {
                  var cssText = rules[j].cssText;
                  if (cssText.indexOf('@media') === 0) {
                      number++;
                      styleSheet.deleteRule(j);
                  }
              }
          }
          if (number) {
              return number;
          }
          return 0;
      }
      
      function removeMediaQueries() {
          var num = removeRule();
          var total = num;
          while (num) {
              num = removeRule();
              total += num;
          }
          if (total) {
              console.info(total + ' media quer' + (total == 1 ? 'y' : 'ies' + ' removed'));
          } else {
              console.info('No media queries removed');
          }
      }
      removeMediaQueries();
      

      如果您将所有这些放在一行中,您可以在浏览器中生成一个书签,并且可以快速测试设计而无需媒体查询。对时事通讯非常有用。

      javascript:!function(){function e(){if("function"!=typeof window.CSSMediaRule)return!1;var e=document.styleSheets,n=0;if(!e)return!1;for(i=0;i<e.length;i++){var o=e[i],r=o.cssRules;if(r)for(var t=0;t<r.length;t++){var f=r[t].cssText;0===f.indexOf("@media")&&(n++,o.deleteRule(t))}}return n?n:0}function n(){for(var i=e(),n=i;i;)i=e(),n+=i;n?console.info(n+" media quer"+(1==n?"y":"ies removed")):console.info("No media queries removed")}n()}();
      

      【讨论】:

        【解决方案3】:

        您最好覆盖它而不是尝试删除它,但如果必须:

        style = document.styleSheets[0]; // or whatever stylesheet you want
        
        [].forEach.call(style.cssRules || [], function(rule, i) {
            if (!rule.cssText.indexOf('@media(min-width:XXXpx') {
                style.deleteRule(i);
            }
        });
        

        未经测试。

        【讨论】:

        • StyleSheetList 没有 forEach 方法。你应该使用 for 循环或[].forEach.call(document.styleSheets, function() { /*...*/ });
        猜你喜欢
        • 2018-02-12
        • 2014-12-09
        • 2022-01-25
        • 2022-11-25
        • 1970-01-01
        • 1970-01-01
        • 2020-05-01
        • 1970-01-01
        • 2017-03-13
        相关资源
        最近更新 更多