2016-10-20 3 views
1

Я использую Bootstrap и Angular.Получить переменную javascript, указывающую текущий тип @media

Я в настоящее время имеют нг-повтор, который установлен вверх, как это:

<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). Основано на ширине бутстрапа шириной в 12 столбцов. Clearfix работает для сброса строки, она видна только для соответствующего размера экрана, а ng-if добавляет ее только к dom, когда индекс соответствует соответствующей строке.

В зависимости от типа носителя (браузера или принтера) добавляется дополнительный загрузочный css. Это связано с тем, что bootstrap обрабатывает весь размер экрана принтера как xs. Я хочу, чтобы при печати печаталось 3 элемента в строке (вместо 2). Чтобы добиться этого, я скрываю директиву при печати при печати и показываю директиву только с определением col-xs-4. Я также скрываю исходное xs clearfix при печати и показываю одно подходящее с col-xs-4.

Все это работает, но проблема в том, что эти классы cssssstrap media css скрываются/отображаются. Это означает, что за сценой есть значительное количество лишнего мусора DOM, который скрыт.

Чтобы обойти мою точку зрения. В настоящее время я отлично разбираюсь в скрытых очищающих экранах экрана, но я бы хотел использовать ng-if вместо классов hidden-print/visible-print, чтобы не дважды писать директиву в DOM.

Каков наилучший способ получить переменную, представляющую текущий тип носителя (принтер/браузер)? Я хочу использовать его как <ng-if currentMediaType == 'print'>, если это возможно.

ответ

1

Если вы обнаружите, что невозможно сделать то, что хотите с помощью css, вы можете обнаружить текущий носитель, используя window.matchMedia(). Например,

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

Параметр - любое допустимое выражение запроса СМИ.

+1

I t стоит отметить, что это не работает в версиях IE до IE10. –

+0

Затем вы можете увидеть https://github.com/paulirish/matchMedia.js – CStff

0

Я делал что-то подобное в проекте 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> 

Затем в угловом заводе, я создал функцию, которая наблюдала за изменяете размеры и выяснил Bootstrap размер, и хранить его для использования/поиска:

(Обратите внимание, что этот код также использует lodash библиотеки для дребезга, 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; 

}]); 
Смежные вопросы