Как определить отзывчивые точки останова Twitter Bootstrap 3 с помощью JavaScript?

В настоящее время, Twitter Bootstrap 3 имеют следующие отзывчивые точки останова: 768px, 992px и 1200px, представляющие малые, средние и большие устройства соответственно.

Как определить эти точки останова с помощью JavaScript?

Я хотел бы прослушать с JavaScript для всех связанных событий, вызванных при смене экрана. И чтобы можно было определить, используется ли экран для небольших, средних или больших устройств.

Что-то уже сделано? Каковы ваши предложения?

Ответ 1

Редактировать: эта библиотека теперь доступна через Бауэр и NPM. Смотрите github repo для подробностей.

ОБНОВЛЕННЫЙ ОТВЕТ:

Отказ от ответственности: я автор.

Вот несколько вещей, которые вы можете сделать, используя последнюю версию (Responsive Bootstrap Toolkit 2.5.0):

// Wrap everything in an IIFE
(function($, viewport){

    // Executes only in XS breakpoint
    if( viewport.is('xs') ) {
        // ...
    }

    // Executes in SM, MD and LG breakpoints
    if( viewport.is('>=sm') ) {
        // ...
    }

    // Executes in XS and SM breakpoints
    if( viewport.is('<md') ) {
        // ...
    }

    // Execute only after document has fully loaded
    $(document).ready(function() {
        if( viewport.is('xs') ) {
            // ...
        }
    });

    // Execute code each time window size changes
    $(window).resize(
        viewport.changed(function() {
            if( viewport.is('xs') ) {
                // ...
            }
        })
    ); 

})(jQuery, ResponsiveBootstrapToolkit);

Начиная с версии 2.3.0, вам не нужны четыре элемента <div>, упомянутых ниже.


ОРИГИНАЛЬНЫЙ ОТВЕТ:

Я не думаю, что вам нужен какой-либо огромный скрипт или библиотека для этого. Это довольно простая задача.

Вставьте следующие элементы непосредственно перед </body>:

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

Эти 4 деления позволяют проверить текущую активную точку останова. Для легкого обнаружения JS используйте следующую функцию:

function isBreakpoint( alias ) {
    return $('.device-' + alias).is(':visible');
}

Теперь, чтобы выполнить определенное действие только с самой маленькой точкой останова, которую вы можете использовать:

if( isBreakpoint('xs') ) {
    $('.someClass').css('property', 'value');
}

Обнаружение изменений после готовности DOM также довольно просто. Все, что вам нужно, это облегченный слушатель с изменением размера окна, как этот:

var waitForFinalEvent = function () {
      var b = {};
      return function (c, d, a) {
        a || (a = "I am a banana!");
        b[a] && clearTimeout(b[a]);
        b[a] = setTimeout(c, d)
      }
    }();

var fullDateString = new Date();

После того, как вы его оснастите, вы можете начать прослушивать изменения и выполнять специфичные для точки останова функции, например:

$(window).resize(function () {
    waitForFinalEvent(function(){

        if( isBreakpoint('xs') ) {
            $('.someClass').css('property', 'value');
        }

    }, 300, fullDateString.getTime())
});

Ответ 2

Если у вас нет конкретных потребностей, вы можете просто сделать это:

if ($(window).width() < 768) {
    // do something for small screens
}
else if ($(window).width() >= 768 &&  $(window).width() <= 992) {
    // do something for medium screens
}
else if ($(window).width() > 992 &&  $(window).width() <= 1200) {
    // do something for big screens
}
else  {
    // do something for huge screens
}

Изменить: я не понимаю, почему вы должны использовать другую библиотеку js, когда вы можете сделать это, только с jQuery, уже включенным в ваш проект Bootstrap.

Ответ 3

Вы взглянули на Response.js? Он предназначен для такого рода вещей. Объедините Response.band и Response.resize.

http://responsejs.com/

Response.resize(function() {
    if ( Response.band(1200) )
    {
       // 1200+
    }    
    else if ( Response.band(992) )
    {
        // 992+
    }
    else if ( Response.band(768) )
    {
        // 768+
    }
    else 
    {
        // 0->768
    }
});

Ответ 4

Вы можете использовать размер окна и жесткий код для контрольных точек. Использование Angular:

angular
    .module('components.responsiveDetection', [])
    .factory('ResponsiveDetection', function ($window) {
        return {
            getBreakpoint: function () {
                var w = $window.innerWidth;
                if (w < 768) {
                    return 'xs';
                } else if (w < 992) {
                    return 'sm';
                } else if (w < 1200) {
                    return 'md';
                } else {
                    return 'lg';
                }
            }
        };
    });

Ответ 5

Определить отзывчивую точку останова Twitter Bootstrap 4.1.x с помощью JavaScript

Bootstrap v.4.0.0 (и последняя версия Bootstrap 4.1.x) представили обновленные параметры сетки, поэтому старая концепция обнаружения может не напрямую применять (см. инструкции по миграции):

  • Добавлен новый уровень сетки sm ниже 768px для более детального контроля. Теперь у нас есть xs, sm, md, lg и xl;
  • xs классы сетки были изменены, чтобы не требовать инфикса.

Я написал небольшую служебную функцию, которая учитывает обновленные имена классов сетки и новый уровень сетки:

/**
 * Detect the current active responsive breakpoint in Bootstrap
 * @returns {string}
 * @author farside {@link https://stackoverflow.com/users/4354249/farside}
 */
function getResponsiveBreakpoint() {
    var envs = {xs:"d-none", sm:"d-sm-none", md:"d-md-none", lg:"d-lg-none", xl:"d-xl-none"};
    var env = "";

    var $el = $("<div>");
    $el.appendTo($("body"));

    for (var i = Object.keys(envs).length - 1; i >= 0; i--) {
        env = Object.keys(envs)[i];
        $el.addClass(envs[env]);
        if ($el.is(":hidden")) {
            break; // env detected
        }
    }
    $el.remove();
    return env;
};

Определение отзывчивой точки останова Bootstrap v4-beta с помощью JavaScript

Bootstrap v4-alpha и Bootstrap v4-beta имели различный подход к точкам останова сетки, поэтому здесь унаследованный способ достижения того же самого:

/**
 * Detect and return the current active responsive breakpoint in Bootstrap
 * @returns {string}
 * @author farside {@link https://stackoverflow.com/users/4354249/farside}
 */
function getResponsiveBreakpoint() {
    var envs = ["xs", "sm", "md", "lg"];
    var env = "";

    var $el = $("<div>");
    $el.appendTo($("body"));

    for (var i = envs.length - 1; i >= 0; i--) {
        env = envs[i];
        $el.addClass("d-" + env + "-none");;
        if ($el.is(":hidden")) {
            break; // env detected
        }
    }
    $el.remove();
    return env;
}

Я думаю, что это будет полезно, так как его легко интегрировать в любой проект. Он использует собственные адаптивные классы отображения самой Bootstrap.

Ответ 6

Здесь мое собственное простое решение:

JQuery

function getBootstrapBreakpoint(){
    var w = $(document).innerWidth();
    return (w < 768) ? 'xs' : ((w < 992) ? 'sm' : ((w < 1200) ? 'md' : 'lg'));
}

VanillaJS:

function getBootstrapBreakpoint(){
    var w = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
    return (w < 768) ? 'xs' : ((w < 992) ? 'sm' : ((w < 1200) ? 'md' : 'lg'));
}

Ответ 7

Использование этого подхода с Response.js лучше. Триггеры Response.resize при каждом изменении размера окна, где кроссовер будет срабатывать только при изменении точки останова.

Response.create({
    prop : "width",
    breakpoints : [1200, 992, 768, 480, 320, 0]
});

Response.crossover('width', function() {
    if (Response.band(1200)) {
        // 1200+

    } else if (Response.band(992)) {
        // 992+

    } else if (Response.band(768)) {
        // 768+

    } else if (Response.band(480)) {
        //480+

    } else {
        // 0->320

    }
});

Response.ready(function() {
    $(window).trigger('resize');
});

Ответ 8

Не должно быть никаких проблем с некоторой ручной реализацией, например, с помощью команды @oozic.

Вот несколько библиотек, которые вы могли бы посмотреть на:

  • Response.js - плагин jQuery - использовать атрибуты данных html, а также js api.
  • enquire.js - enquire.js представляет собой легкую, чистую библиотеку JavaScript для ответа на запросы в формате CSS.
  • SimpleStateManager - это менеджер состояния javascript для чувствительных веб-сайтов. Он построен как легкий, не имеет зависимости.

Обратите внимание, что эти библиотеки предназначены для работы независимо от начальной загрузки, создания и т.д. Вы можете настроить свои собственные контрольные точки и получать удовольствие.

Ответ 9

Возможно, вы захотите добавить это в свой проект начальной загрузки, чтобы визуально проверить активную точку останова

    <script type='text/javascript'>

        $(document).ready(function () {

            var mode;

            $('<div class="mode-informer label-info" style="z-index:1000;position: fixed;bottom:10px;left:10px">%mode%</div>').appendTo('body');


            var checkMode = function () {

                if ($(window).width() < 768) {
                    return 'xs';
                }
                else if ($(window).width() >= 768 && $(window).width() < 992) {
                    return 'sm';
                }
                else if ($(window).width() >= 992 && $(window).width() < 1200) {
                    return 'md';
                }
                else {
                    return 'lg';
                }
            };

            var compareMode = function () {
                if (mode !== checkMode()) {
                    mode = checkMode();

                    $('.mode-informer').text(mode).animate({
                        bottom: '100'
                    }, 100, function () {
                        $('.mode-informer').animate({bottom: 10}, 100)
                    });
                }
            };

            $(window).on('resize', function () {
                compareMode()
            });

            compareMode();

        });

    </script>

Вот BOOTPLY

Ответ 10

Основываясь на ответе Мачей Гурбана (это фантастично... если вам это нравится, просто проголосуйте за его ответ). Если вы создаете услугу для запроса, вы можете вернуть текущую активную услугу с настройкой ниже. Это может полностью заменить другие библиотеки обнаружения точки останова (например, enquire.js, если вы введете некоторые события). Обратите внимание, что я добавил контейнер с идентификатором в элементы DOM, чтобы ускорить обход DOM.

HTML

<div id="detect-breakpoints">
    <div class="breakpoint device-xs visible-xs"></div>
    <div class="breakpoint device-sm visible-sm"></div>
    <div class="breakpoint device-md visible-md"></div>
    <div class="breakpoint device-lg visible-lg"></div>
</div>

COFFEESCRIPT (AngularJS, но это легко конвертируется)

# this simple service allows us to query for the currently active breakpoint of our responsive app
myModule = angular.module('module').factory 'BreakpointService', ($log) ->

  # alias could be: xs, sm, md, lg or any over breakpoint grid prefix from Bootstrap 3
  isBreakpoint: (alias) ->
    return $('#detect-breakpoints .device-' + alias).is(':visible')

  # returns xs, sm, md, or lg
  getBreakpoint: ->
    currentBreakpoint = undefined
    $visibleElement = $('#detect-breakpoints .breakpoint:visible')
    breakpointStringsArray = [['device-xs', 'xs'], ['device-sm', 'sm'], ['device-md', 'md'], ['device-lg', 'lg']]
    # note: _. is the lodash library
    _.each breakpointStringsArray, (breakpoint) ->
      if $visibleElement.hasClass(breakpoint[0])
        currentBreakpoint = breakpoint[1]
    return currentBreakpoint

JAVASCRIPT (AngularJS)

var myModule;

myModule = angular.module('modules').factory('BreakpointService', function($log) {
  return {
    isBreakpoint: function(alias) {
      return $('#detect-breakpoints .device-' + alias).is(':visible');
    },
    getBreakpoint: function() {
      var $visibleElement, breakpointStringsArray, currentBreakpoint;
      currentBreakpoint = void 0;
      $visibleElement = $('#detect-breakpoints .breakpoint:visible');
      breakpointStringsArray = [['device-xs', 'xs'], ['device-sm', 'sm'], ['device-md', 'md'], ['device-lg', 'lg']];
      _.each(breakpointStringsArray, function(breakpoint) {
        if ($visibleElement.hasClass(breakpoint[0])) {
          currentBreakpoint = breakpoint[1];
        }
      });
      return currentBreakpoint;
    }
  };
});

Ответ 12

Почему бы просто не использовать jQuery для определения текущей ширины css класса контейнера bootstrap?

ie..

if( parseInt($('#container').css('width')) > 1200 ){
  // do something for desktop screens
}

Вы также можете использовать $(window).resize(), чтобы предотвратить компоновку "загрязнение кровати", если кто-то изменит размер окна браузера.

Ответ 13

Вместо того, чтобы вставлять ниже много раз на каждую страницу...

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

Просто используйте JavaScript, чтобы динамически вставлять его на каждую страницу (обратите внимание, что я обновил его для работы с Bootstrap 3 с помощью .visible-*-block:

// Make it easy to detect screen sizes
var bootstrapSizes = ["xs", "sm", "md", "lg"];
for (var i = 0; i < bootstrapSizes.length; i++) {
    $("<div />", {
        class: 'device-' + bootstrapSizes[i] + ' visible-' + bootstrapSizes[i] + '-block'
    }).appendTo("body");
}

Ответ 14

У меня недостаточно комментариев для комментариев, но для тех, у кого возникают проблемы с получением "непризнанных", когда они пытаются использовать Maciej Gurban ResponsiveToolKit, я также получал эту ошибку, пока не заметил, что Maciej фактически ссылается на набор инструментов из нижней части страницы в его CodePen

Я попытался это сделать, и вдруг это сработало! Итак, используйте RespiveToolkit, но поместите свои ссылки в нижней части страницы:

Я не знаю, почему это имеет значение, но это так.

Ответ 15

Вот еще один способ обнаружить текущий видовой экран без, поместив в ваш javascript номера размеров видовых экранов.

Смотрите фрагменты css и javascript здесь: https://gist.github.com/steveh80/288a9a8bd4c3de16d799

После добавления этих фрагментов к вашим файлам css и javascript вы можете обнаружить текущее окно просмотра следующим образом:

viewport.is('xs') // returns boolean

Если вы хотите определить диапазон просмотра, используйте его так:

viewport.isEqualOrGreaterThan('sm') // returns true for sm, md and lg

Ответ 16

Bootstrap CSS для класса .container выглядит следующим образом:

.container {
    padding-right: 15px;
    padding-left: 15px;
    margin-right: auto;
    margin-left: auto;
}
@media (min-width: 768px) {
    .container {
        width: 750px;
    }
}
@media (min-width: 992px) {
    .container {
        width: 970px;
    }
}
@media (min-width: 1200px) {
    .container {
        width: 1170px;
    }
}

Таким образом, это означает, что мы можем надежно полагаться на jQuery('.container').css('width') для обнаружения точек останова без недостатков, связанных с jQuery(window).width().

Мы можем написать такую ​​функцию:

function detectBreakpoint() {
    // Let ensure we have at least 1 container in our pages.
    if (jQuery('.container').length == 0) {
        jQuery('body').append('<div class="container"></div>');
    }

    var cssWidth = jQuery('.container').css('width');

    if (cssWidth === '1170px') return 'lg';
    else if (cssWidth === '970px') return 'md';
    else if (cssWidth === '750px') return 'sm';

    return 'xs';
}

И затем проверьте его как

jQuery(document).ready(function() {
    jQuery(window).resize(function() {
        jQuery('p').html('current breakpoint is: ' + detectBreakpoint());
    });

    detectBreakpoint();
});

Ответ 17

Используйте свойство CSS :before и content для печати состояния точки останова в <span id="breakpoint-js">, поэтому JavaScript просто должен прочитать эти данные, чтобы превратить его как переменную, используемую в вашей функции.

(запустите фрагмент, чтобы увидеть пример)

ПРИМЕЧАНИЕ. Я добавил несколько строк CSS, чтобы использовать <span> как красный флаг в верхнем углу моего браузера. Просто убедитесь, что вы вернетесь к display:none;, прежде чем публиковать свои материалы.

// initialize it with jquery when DOM is ready
$(document).on('ready', function() {
    getBootstrapBreakpoint();
});

// get bootstrap grid breakpoints
var theBreakpoint = 'xs'; // bootstrap336 default = mobile first
function getBootstrapBreakpoint(){
   theBreakpoint = window.getComputedStyle(document.querySelector('#breakpoint-js'),':before').getPropertyValue('content').replace(/['"]+/g, '');
   console.log('bootstrap grid breakpoint = ' + theBreakpoint);
}
#breakpoint-js {
  /* display: none; //comment this while developping. Switch back to display:NONE before commit */
  /* optional red flag layout */
  position: fixed;
  z-index: 999;
  top: 0;
  left: 0;
  color: white;
  padding: 5px 10px;
  background-color: red;
  opacity: .7;
  /* end of optional red flag layout */
}
#breakpoint-js:before {
  content: 'xs'; /* default = mobile first */
}
@media screen and (min-width: 768px) {
  #breakpoint-js:before {
    content: 'sm';
  }
}
@media screen and (min-width: 992px) {
  #breakpoint-js:before {
    content: 'md';
  }
}
@media screen and (min-width: 1200px) {
  #breakpoint-js:before {
    content: 'lg';
  }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">

<div class="container">
  <span id="breakpoint-js"></span>
  <div class="page-header">
    <h1>Bootstrap grid examples</h1>
    <p class="lead">Basic grid layouts to get you familiar with building within the Bootstrap grid system.</p>
  </div>
</div>

Ответ 18

Я создал собственный метод jQuery для определения размера экрана Twitter Bootstrap. Вот:

// Screen size ID will be stored in this variable (global var for JS)
var CurrentBootstrapScreenSize = 'unknown';

$(document).ready(function () {

    // <div> objects for all screen sizes required for screen size detection.
    // These <div> is hidden for users eyes.
    var currentScreenSizeDetectorObjects = $('<div>').css({
            'position':'absolute',
            'top':'-200px'
        }).addClass('current-screen-size').append([
            $('<div>').addClass('device-xs visible-xs').html('&nbsp;'),
            $('<div>').addClass('device-sm visible-sm').html('&nbsp;'),
            $('<div>').addClass('device-md visible-md').html('&nbsp;'),
            $('<div>').addClass('device-lg visible-lg').html('&nbsp;')
        ]);

    // Attach <div> objects to <body>
    $('body').prepend(currentScreenSizeDetectorObjects);

    // Core method for detector
    function currentScreenSizeDetectorMethod() {
        $(currentScreenSizeDetectorObjects).find('div').each(function() {
            var className = $(this).attr('class');
            if($(this).is(':visible')) {
                if(String(className).match(/device-xs/)) CurrentBootstrapScreenSize = 'xs';
                else if(String(className).match(/device-sm/)) CurrentBootstrapScreenSize = 'sm';
                else if(String(className).match(/device-md/)) CurrentBootstrapScreenSize = 'md';
                else if(String(className).match(/device-lg/)) CurrentBootstrapScreenSize = 'lg';
                else CurrentBootstrapScreenSize = 'unknown';
            };
        })
        console.log('Current Bootstrap screen size is: '+CurrentBootstrapScreenSize);
        $('.CurrentBootstrapScreenSize').first().html('Bootstrap current screen size: <b>' + CurrentBootstrapScreenSize + '</b>' );
    }

    // Bind screen size and orientation change
    $(window).bind("resize orientationchange", function() {
        // Execute screen detection
        currentScreenSizeDetectorMethod();
    });

    // Execute screen detection on page initialize
    currentScreenSizeDetectorMethod();

});

JSFillde: https://jsfiddle.net/pstepniewski/7dz6ubus/

JSFillde в качестве полноэкранного примера: https://jsfiddle.net/pstepniewski/7dz6ubus/embedded/result/

Ответ 19

Для тех, кто заинтересован в этом, я написал определение точек останова на основе точек останова CSS с использованием TypeScript и Observables. сделать ES6 из него не очень сложно, если вы удалите типы. В моем примере я использую Sass, но это также легко удалить.

Вот мой JSFiddle: https://jsfiddle.net/StefanJelner/dorj184g/

HTML:

<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.7/Rx.min.js"></script>
<div id="result"></div>

SCSS:

body::before {
  content: 'xs';
  display: none;

  @media screen and (min-width: 480px) {
    content: 's';
  }

  @media screen and (min-width: 768px) {
    content: 'm';
  }

  @media screen and (min-width: 1024px) {
    content: 'l';
  }

  @media screen and (min-width: 1280px) {
    content: 'xl';
  }
}

Машинопись:

import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { Observable } from 'rxjs/Observable';

class BreakpointChangeService {
    private breakpointChange$: BehaviorSubject<string>;

    constructor(): BehaviorSubject<string> {
        // initialize BehaviorSubject with the current content of the ::before pseudo element
        this.breakpointChange$ = new Rx.BehaviorSubject(this.getBreakpoint());

        // observe the window resize event, throttle it and combine it with the BehaviorSubject
        Rx.Observable
            .fromEvent(window, 'resize')
            .throttleTime(0, Rx.Scheduler.animationFrame)
            .withLatestFrom(this.breakpointChange$)
            .subscribe(this.update.bind(this))
        ;

        return this.breakpointChange$;
    }

    // method to get the content of the ::before pseudo element
    private getBreakpoint(): string {
        // see https://www.lullabot.com/articles/importing-css-breakpoints-into-javascript
        return window.getComputedStyle(document.body, ':before').getPropertyValue('content').replace(/[\"\']/g, '');
    }

    private update(_, recent): void {
        var current = this.getBreakpoint();
        if(recent !== current) { this.breakpointChange$.next(current); }
    }
}

// if the breakpoint changes, react on it
var $result = document.getElementById('result');
new BreakpointChangeService().subscribe(breakpoint => {
    $result.innerHTML = Date.now()+': '+breakpoint;
});

Надеюсь, это кому-нибудь поможет.

Ответ 20

Bootstrap4 с jQuery, упрощенное решение

<div class="device-sm d-sm-none"></div>
<div class="device-md d-md-none"></div>
<div class="device-lg d-lg-none"></div>
<div class="device-xl d-xl-none"></div>
<script>
var size = $('.device-xl').is(':hidden') ? 'xl' : ($('.device-lg').is(':hidden') ? 'lg'
    : ($('.device-md').is(':hidden') ? 'md': ($('.device-sm').is(':hidden') ? 'sm' : 'xs')));
alert(size);
</script>

Ответ 21

Я не был действительно удовлетворен данными ответами, которые мне кажутся слишком сложными, поэтому я написал свое собственное решение. Однако на данный момент это зависит от подчеркивания /lodash для работы.

https://github.com/LeShrimp/GridSizeEvents

Вы можете использовать это так:

GridSizeEvents.addListener(function (newSize, oldSize) {
    // Will output eg. "xs -> sm"
    console.log(oldSize + ' -> ' + newSize);
});

Это работает из коробки для Bootstrap 3, поскольку точки останова жестко запрограммированы на 768px, 992px и 1200px. Для других версий вы можете легко адаптировать код.

Внутренне это использует matchMedia() и, таким образом, должно гарантировать получение результатов, которые синхронизированы с Bootstrap.

Ответ 22

Может быть, это поможет некоторым из вас, но есть плагин, который поможет вам определить, на какой текущей начальной точке загрузки v4 вы видите: https://www.npmjs.com/package/bs-breakpoints

Простой в использовании (можно использовать с или без jQuery):

$(document).ready(function() {
  bsBreakpoints.init()
  console.warn(bsBreakpoint.getCurrentBreakpoint())

  $(window).on('new.bs.breakpoint', function (event) {
    console.warn(event.breakpoint)
  })
})

Ответ 23

Для тех, кто использует knockout.js, мне нужны некоторые свойства knockout.js, которые могли бы сказать мне, когда контрольные точки ударяются. Я решил использовать поддержку Modernizr для медиа-запросов css-стиля, чтобы числа соответствовали определениям бутстрапа и получали преимущества совместимости с modernizr. Моя модель нокаута выглядит следующим образом:

var viewModel = function() {
    // depends on jquery, Modernizr
    var self = this;
    self.widthXsOrLess = ko.observable();
    self.widthSmOrLess = ko.observable();
    self.widthMdOrLess = ko.observable();
    var setWindowSizeVars = function() {
        self.widthXsOrLess(!Modernizr.mq('(min-width: 768px)'));
        self.widthSmOrLess(!Modernizr.mq('(min-width: 992px)'));
        self.widthMdOrLess(!Modernizr.mq('(min-width: 1200px)'));
    };
    $(window).resize(setWindowSizeVars);
    setWindowSizeVars();
};

Ответ 24

Вот хороший способ его обнаружить (может быть, смешно, но работает), и вы можете использовать необходимый элемент, чтобы код был ясен:

Пример: CSS:

@media (max-width: 768px) {
    #someElement
    {
         background: pink
    }
}

и в документе jQuery:

if($('#someElement').css('background') == 'pink')
{
    doWhatYouNeed();
}

конечно, свойство css - любое.

Ответ 25

Так как bootstrap 4 скоро выйдет, я подумал, что буду использовать функцию, которая его поддерживает (xl теперь вещь) и выполняет минимальное jQuery, чтобы выполнить задание.

/**
 * Get the Bootstrap device size
 * @returns {string|boolean} xs|sm|md|lg|xl on success, otherwise false if Bootstrap is not working or installed
 */
function findBootstrapEnvironment() {
    var environments = ['xs', 'sm', 'md', 'lg', 'xl'];
    var $el = $('<span />');
    $el.appendTo($('body'));
    for (var i = environments.length - 1; i >= 0; i--) {
        var env = environments[i];
        $el.addClass('hidden-'+env);
        if ($el.is(':hidden')) {
            $el.remove();
            return env;
        }
    }
    $el.remove();
    return false;
}

Ответ 26

Bootstrap 4

setResponsiveDivs();

function setResponsiveDivs() {
    var data = [
        {id: 'visible-xs', class: 'd-block d-sm-none'},
        {id: 'visible-sm', class: 'd-none d-sm-block d-md-none'},
        {id: 'visible-md', class: 'd-none d-md-block d-lg-none'},
        {id: 'visible-lg', class: 'd-none d-lg-block d-xl-none'},
        {id: 'visible-xl', class: 'd-none d-xl-block'}
    ];

    for (var i = 0; i < data.length; i++) {
        var el = document.createElement("div");
        el.setAttribute('id', data[i].id);
        el.setAttribute('class', data[i].class);
        document.getElementsByTagName('body')[0].appendChild(el);
    }
}

function isVisible(type) {
    return window.getComputedStyle(document.getElementById('visible-' + type), null).getPropertyValue('display') === 'block';
}

// then, at some point
window.onresize = function() {
    console.log(isVisible('xs') === true ? 'xs' : '');
    console.log(isVisible('sm') === true ? 'sm' : '');
    console.log(isVisible('md') === true ? 'md' : '');
    console.log(isVisible('lg') === true ? 'lg' : '');
    console.log(isVisible('xl') === true ? 'xl' : '');
};

Ответ 27

Если вы используете Нокаут, вы можете использовать следующую настраиваемую привязку, чтобы привязать текущую точку останова просмотра (xs, sm, md или lg) к наблюдаемой в вашей модели. Связывание...

  • обертывает 4 divs классом visible-?? в div с id detect-viewport и добавляет его в тело, если он еще не существует (чтобы вы могли повторно использовать эту привязку, не дублируя эти div)
  • устанавливает текущую точку останова в окне просмотра, связанную с наблюдаемой, запрашивая, какая из divs видима
  • обновляет текущую точку останова в окне просмотра при изменении размера окна

ko.bindingHandlers['viewport'] = {
    init: function(element, valueAccessor) {
        if (!document.getElementById('detect-viewport')) {
            let detectViewportWrapper = document.createElement('div');
            detectViewportWrapper.id = 'detect-viewport';
            
            ["xs", "sm", "md", "lg"].forEach(function(breakpoint) {
                let breakpointDiv = document.createElement('div');
                breakpointDiv.className = 'visible-' + breakpoint;
                detectViewportWrapper.appendChild(breakpointDiv);
            });

            document.body.appendChild(detectViewportWrapper);
        }

        let setCurrentBreakpoint = function() {
            valueAccessor()($('#detect-viewport div:visible')[0].className.substring('visible-'.length));
        }
      
        $(window).resize(setCurrentBreakpoint);
        setCurrentBreakpoint();
    }
};

ko.applyBindings({
  currentViewPort: ko.observable()
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>

<div data-bind="viewport: currentViewPort"></div>
<div>    
    Current viewport breakpoint: <strong data-bind="text: currentViewPort"></strong>
</div>
<div>
    (Click the <em>full page</em> link of this snippet to test the binding with different window sizes)
</div>

Ответ 28

Со времени OP прошло некоторое время, но здесь мое решение для этого было основано на Bootstrap 3. В моем случае я использовал только строки, но то же самое можно было применить к контейнеру и т.д.

Просто измените .row на то, что вы хотите.

jQuery(document).ready(function ($) {

    var alterClass = function () {

        var ww = document.body.clientWidth;

        if (ww < 768) {

            $('.row').addClass('is-xs').removeClass('is-sm').removeClass('is-lg').removeClass('is-md');

        } else if (ww >= 768 && ww < 992) {

            $('.row').addClass('is-sm').removeClass('is-xs').removeClass('is-lg').removeClass('is-md');

        } else if (ww >= 992 && ww < 1200) {

            $('.row').addClass('is-md').removeClass('is-xs').removeClass('is-lg').removeClass('is-sm');

        } else if (ww >= 1200) {

            $('.row').addClass('is-lg').removeClass('is-md').removeClass('is-sm').removeClass('is-xs');

        };
    };

    // Make Changes when the window is resized
    $(window).resize(function () {
        alterClass();
    });

    // Fire when the page first loads
    alterClass();
});