获取一个指示当前@media 类型的 javascript 变量

Posted

技术标签:

【中文标题】获取一个指示当前@media 类型的 javascript 变量【英文标题】:Get a javascript variable indicating current @media type 【发布时间】:2017-03-02 18:32:26 【问题描述】:

我正在使用 Bootstrap 和 Angular。

我目前有一个这样设置的 ng-repeat:

<div class="row">
   <div ng-if="viewType == 'grid'">
      <div ng-repeat="product in filteredProducts | filter:search" >
         <product-tile-view class="hidden-print col-lg-2 col-md-3 col-sm-4 col-xs-6" product="product" on-selected="deviceSelected(product)" on-compare="compare(product)"></product-tile-view>
         <product-tile-view class="visible-print-block col-xs-4" product="product" on-selected="deviceSelected(product)" on-compare="compare(product)"></product-tile-view>
         <div class="clearfix visible-lg" ng-if="($index + 1) % 6 == 0"></div>
         <div class="clearfix visible-md" ng-if="($index + 1) % 4 == 0"></div>
         <div class="clearfix visible-sm" ng-if="($index + 1) % 3 == 0"></div>
         <div class="hidden-print clearfix visible-xs" ng-if="($index + 1) % 2 == 0"></div>
         <div class="visible-print-inline clearfix visible-xs" ng-if="($index + 1) % 3 == 0"></div>
      </div>
 ...other unreleated code, divs are closed.

这确实有效。简要说明它在做什么:

根据屏幕大小,行包含 6 个项目 (lg-2)、4 个项目 (md-3)、3 个项目 (sm-4) 或 2 个项目 (xs-6)。基于 bootstrap 的 12 列宽。 clearfix 用于重置行,它仅在适当的屏幕尺寸下可见,并且 ng-if 仅在索引与适当的行匹配时将其添加到 dom。

根据媒体类型(浏览器或打印机),添加额外的引导 css。这是因为 bootstrap 将所有打印机屏幕尺寸视为 xs。打印时我想要每行 3 个项目(而不是 2 个)。为了做到这一点,我在打印时隐藏了响应指令,并显示了一个只定义了 col-xs-4 的指令。我还在打印时隐藏了原始的 xs clearfix,并使用 col-xs-4 显示一个合适的。

所有这些都有效,但问题是这些引导媒体 css 类正在隐藏/显示。这意味着在幕后,隐藏着大量额外的 DOM 垃圾。

绕开我的观点。我现在对隐藏的屏幕大小的 clearfixes 很好,但我想使用 ng-if 而不是 hidden-print / visible-print 类来不将指令写入 DOM 两次。

基本上获取表示当前媒体类型(打印机/浏览器)的变量的最佳方法是什么?如果可能的话,我想像&lt;ng-if currentMediaType == 'print'&gt; 一样使用它。

【问题讨论】:

【参考方案1】:

如果您发现无法使用 css 制作您想要的内容,您可以使用 window.matchMedia() 检测当前媒体。例如

var is_screen = window.matchMedia("screen").matches;  //bool 
var is_tv = window.matchMedia("tv").matches;           

参数是任何有效的媒体查询表达式。

【讨论】:

值得注意的是,这在IE10之前的IE版本中不起作用。 window.styleMedia.type 获取而不是 --> 为您提供确切的类型,而不必明确检查每个类型【参考方案2】:

可以直接从window.styleMedia.type获取

【讨论】:

请不要这样做:window.styleMediawindow.matchMedia 的已弃用 API 草案,未在 Firefox 中实现,将来会从 Web 平台中删除。在 Chrome 中,window.styleMedia.type 似乎只返回 "screen",因为 print() 是同步的(阻塞)。【参考方案3】:

我在我正在处理的一个 Angular 项目中做了类似的事情。结果证明效果很好。我能够根据当前引导大小显示/隐藏某些指令和标记。

我确信它可以被增强以支持打印/屏幕媒体类。

这是我所拥有的核心,您可以根据需要进行修改。

在我的标记中,我添加了四个元素,以便我可以使用 Angular “观察”它们:

<span class="device-xs visible-xs"></span>
<span class="device-sm visible-sm"></span>
<span class="device-md visible-md"></span>
<span class="device-lg visible-lg"></span>

然后,在一个 Angular 工厂中,我创建了一个函数来监视调整大小并计算出 Bootstrap 大小,并将其存储起来以供使用/检索:

(请注意,此代码还使用 lodash 库来实现 debounce、forEach 和其他有用的实用程序)

angular.module('myApp.services').factory('utility', ['$route', '$window', '$filter', function ($route, $window, $filter) 

  var factory = ;

  // Local store for current window width
  factory.windowWidth = $window.innerWidth;

  // Local store for current bootstrap size
  factory.bootstrapSize = '';

  /**
   * Determines which bootstrap kick size we are on (xs, md, etc)
   * NOTE: Relies on the elements being placed on the template somewhere:
   *  .device-xs.visible-xs
   *  .device-sm.visible-sm
   *  .device-md.visible-md
   *  .device-lg.visible-lg
   */
  factory.findKick = function () 
    var kicks = ['xs', 'sm', 'md', 'lg'];
    var newkick = '';
    _.forEach(kicks, function (size) 
      var className = '.device-' + size;
      if (factory.isVisible(className)) 
        newkick = size;
        factory.bootstrapSize = size;
        return false;
      
    );
    if (!newkick) 
       // Do something to log / trap this situation
    
    return factory.bootstrapSize;
  ;

  /**
   * Determines if the passed in element is visible or not
   *
   * @param className
   * @returns boolean
   */
  factory.isVisible = function (className) 
    return angular.element(className).is(':visible');
  ;

  /**
   * Watch for window resizes and executes a debounced function to set the window width
   *
   * @type Function
   */
  var w = angular.element($window);
  w.bind('resize', _.debounce(function () 
    factory.windowWidth = $window.innerWidth;
    factory.findKick();
  , 250));

  // Trigger the bootstrap size immediately on load.
  factory.findKick();

  return factory;

]);

【讨论】:

以上是关于获取一个指示当前@media 类型的 javascript 变量的主要内容,如果未能解决你的问题,请参考以下文章

针对不同媒体查询的不同 CSS 文件

MEDIA12899:音频/视频:未知 MIME 类型:

从 Spotfiy API 请求令牌时获取 415 Unsupported Media Type

document和javaScript内置对象

DataTime? 的 GetValueOrDefault() 方法

Java实现企业微信上传临时文件获取media_id