Як виявити чуйні точки перерви Twitter Bootstrap 3 за допомогою JavaScript?


139

Наразі Twitter Bootstrap 3 має такі точки чуйного прориву: 768px, 992px та 1200px, що представляє собою відповідно малі, середні та великі пристрої.

Як я можу виявити ці точки перерви за допомогою JavaScript?

Я хотів би послухати JavaScript за всіма пов’язаними подіями, що виникають при зміні екрана. І мати можливість виявити, чи екран для маленьких, середніх чи великих пристроїв.

Чи щось вже зроблено? Які ваші пропозиції?


Ви можете використовувати IntersectionObserver, щоб виявити, коли <div class="d-none d-?-block"></div>зміниться видимість (вставте бажану точку розриву). Ці класи CSS призначені для Bootstrap 4 ... використовувати все, що працює в Bootstrap 3. Набагато ефективніше, ніж прослуховування події зміни розміру вікон.
Метт Томас

Відповіді:


241

Редагувати: Ця бібліотека тепер доступна через Bower та 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())
});

3
Не працює для мене. viewport.current () завжди дає "нерозпізнаний". Чи я щось роблю не так?
зоряні клопи

У вас є загадка? Редагувати: Можливо, ви включили замість корпусу свої сценарії, включаючи RBT у розділ голови? Це не дозволить додавати диви видимості до тіла, тим самим порушуючи функціональність.
Мацей Гурбан

@MaciejGurban Я також не можу змусити його працювати. Я використовую Rails 4.2. Я включаю завантажувальний засіб в голову, але ваш сценарій в тілі, але він все ще не розпізнається. Добре моя проблема, я додав все в організмі. Але чи справді це потрібно?
Денніс

Ще раз важко сказати проблему без скрипки чи зразкового коду. Ви можете задати питання про нього на SO та посилатися тут, або відкрити випуск на github. Ви дотримувались порядку включення всіх деталей, як це є у CodePen ? Чи тільки ця функція не працює? Чи може бути проблема такою ?
Мацей Гурбан

1
Як це можна було використовувати з завантажувальним інструментом 4?
Калонтар

64

Якщо у вас немає конкретних потреб, ви можете просто зробити це:

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.


Дякую, чи можете ви також надати слухача всі події, які викликають зміну розміру екрана?
Рубенс Маріуццо

Я не думаю, що існують події щодо зміни розміру екрана. Все, що стосується розмірності екрана (медіа-запити), знаходиться в таблиці стилів.
mtt

2
Я це знаю, я просто шукаю подібну поведінку в JS. Насправді слухайте про зміну розміру екрана за допомогою: $(window).bind('resize')... але є й інші події, пов'язані з орієнтацією на мобільний екран, які впливають на розмір екрана.
Рубенс Маріуццо

Орієнтація на пристрій все ще є експериментальною функцією: developer.mozilla.org/en-US/docs/Web/API/DeviceOrientationEvent Я пропоную вам скористатися.on('resize')
mtt

1
Я чув про випадки, коли такий спосіб виявлення стану викликає проблеми. Краще спробувати щось перевірити, чи є видимі допоміжні елементи імхо - просто щоб бути в безпеці від будь-яких кутових випадків.
Мануель Арвед Шмідт

11

Ви подивилися на 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
    }
});

Цікава бібліотека, хоча вона не була розроблена на увазі Twitter Bootstrap 3. У будь-якому випадку, схоже, що його можна легко адаптувати до TWBS3.
Рубенс Маріуццо

11

Ви можете використовувати розмір вікна та жорсткий код точок прориву. Використання кутових:

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';
                }
            }
        };
    });

Мені подобається ця відповідь. Не потрібні інші бібліотеки (навіть jQuery).
dprothero

11

Виявити чуйну точку розриву Twitter Bootstrap 4.1.x за допомогою JavaScript

V.4.0.0 Bootstrap (і остання версія 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-альфа і Bootstrap v4-бета мали різний підхід до сітки контрольних точок, так ось у спадок спосіб досягнення тієї ж:

/**
 * 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;
}

Думаю, це було б корисно, оскільки легко інтегруватися до будь-якого проекту. Він використовує нативні класи відображення самого завантажувального пристрою.


7

Ось моє власне просте рішення:

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'));
}

5

Краще використовувати цей підхід з 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');
});

4

Не повинно виникнути проблем з ручним реалізацією на зразок тієї, яку згадував @oozic.

Ось пару гілок, на які ви могли поглянути:

  • Response.js - плагін jQuery - використовує атрибути даних html, а також має js api.
  • enquire.js - enquire.js - це легка, чиста бібліотека JavaScript для відповіді на запити медіа CSS
  • SimpleStateManager - менеджер стану javascript для чуйних веб-сайтів. Він побудований для легкої ваги, не має залежностей.

Зауважте, що ці лінзи призначені для роботи незалежно від завантажувальної стрічки, фундаменту тощо. Ви можете налаштувати власні точки перерви та розважитися.


3
Enquire.js виглядає перспективно.
Рубенс Маріуццо

4

Ви можете додати це до проекту завантаження, щоб візуально перевірити активну точку розриву

    <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>

Ось БУТИ


4

Спираючись на відповідь Мацея Гурбана (що фантастично ... якщо вам це подобається, будь ласка, просто проголосуйте його відповідь). Якщо ви створюєте службу для запиту, ви можете повернути поточно активну послугу з налаштуваннями нижче. Це може повністю замінити інші бібліотеки виявлення точок розриву (наприклад, 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;
    }
  };
});

3

Замість використання $ (document) .width (), вам слід встановити правило CSS, яке дає вам цю інформацію.

Я щойно написав статтю, щоб її точно зрозуміти. Дивіться це тут: http://www.xurei-design.be/2013/10/how-to-accurely-detect-responsive-breakpoints/


Це найкращий підхід в моєї точки зору , як описано в цій відповіді: stackoverflow.com/a/22885503/439427
Рубенс Mariuzzo

3

Чому б не просто використати jQuery для виявлення поточної ширини css класу контейнерів завантажувальної машини?

тобто ..

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

Ви також можете використовувати $ (window) .resize (), щоб запобігти "мазання ліжка" вашого макета, якщо хтось змінить розмір вікна браузера.


3

Замість того, щоб вставляти вказане нижче багато разів у кожну сторінку ...

<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");
}

2

У мене не вистачає репутаційних очок для коментарів, але для тих, у кого виникають проблеми з «невизнанням», коли вони намагаються використовувати ResponseToolKit Maciej Gurban, я також отримував цю помилку, поки я не помітив, що Maciej насправді посилається на інструментарій знизу сторінки в його CodePen

Я спробував це зробити і раптом це спрацювало! Отже, використовуйте RespovableToolkit, але покладіть свої посилання внизу сторінки:

Я не знаю, чому це має значення, але це так.


2

Ось ще один спосіб виявити поточний вікно перегляду, не додаючи номери розміру вікна перегляду у вашому 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

2

CSS Bootstrap для .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's 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();
});

Це буде працювати лише на заданій ширині; нічого середнього не вийде. Можливо, найкраще: По-перше, розібратися на cssWidth var cssWidth = parseInt( jQuery('.container').css('width') ); Друге, використовувати діапазони if ( cssWidth < 768) { return 'xs'; } else if (cssWidth >= 768 && cssWidth <= 992) { return 'sm'; } else if (cssWidth > 992 && cssWidth <= 1200) { return 'md'; } else { return 'lg'; }
kakoma

2

Використовуйте 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>


1

Я створив власний метод 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/


1

Для всіх, хто зацікавився цим, я написав виявлення точки перерви на основі 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';
  }
}

TypeScript:

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;
});

Я сподіваюся, що це комусь допоможе.


1

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>

1

Я не був дуже задоволений наданими відповідями, які мені здаються надто складними, тому я написав власне рішення. Однак поки що це покладається на підкреслення / подачу роботи.

https://github.com/LeShrimp/GridSizeEvents

Ви можете використовувати його так:

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

Це спрацьовує з поля Box Bootstrap 3, оскільки точки прориву жорстко кодуються до 768px, 992px та 1200px. Для інших версій ви можете легко адаптувати код.

Внутрішньо для цього використовується matchMedia () і, таким чином, слід гарантувати отримання результатів, які синхронізуються з Bootstrap.


1

Можливо, це допоможе комусь із вас, але є плагін, який допоможе вам виявити, на якій поточній точці розриву Bootstrap 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)
  })
})

1

Ось моє рішення (Bootstrap 4):

<div class="alert alert-warning row">
    <div class="col">
        Bootstrap breakpoint is
    </div>
    <div class="col">
        <div class="d-block d-sm-none">
            XS
        </div>
        <div class="d-none d-sm-block d-md-none">
            SM
        </div>
        <div class="d-none d-md-block d-lg-none">
            MD
        </div>
        <div class="d-none d-lg-block d-xl-none">
            MD
        </div>
        <div class="d-none d-xl-block">
            MD
        </div>
    </div>
</div>

0

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

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();
};

0

Ось хороший спосіб його виявити (можливо, смішно, але працює), і ви можете використовувати необхідний елемент, щоб код був зрозумілим:

Приклад: css:

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

та в документі jQuery:

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

звичайно, властивість css є будь-якою.


0

Оскільки завантажувальний сервіс 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;
}

0

Завантаження 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' : '');
};

або мінімізований

function setResponsiveDivs(){for(var e=[{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"}],s=0;s<e.length;s++){var l=document.createElement("div");l.setAttribute("id",e[s].id),l.setAttribute("class",e[s]["class"]),document.getElementsByTagName("body")[0].appendChild(l)}}function isVisible(e){return"block"===window.getComputedStyle(document.getElementById("visible-"+e),null).getPropertyValue("display")}setResponsiveDivs();


0

Якщо ви використовуєте Knockout , ви можете використовувати наступне спеціальне прив'язування, щоб прив’язати поточну точку огляду огляду (xs, sm, md або lg) до спостережуваної у вашій моделі. Прив'язка ...

  • загортає 4 divsз visible-??класом у діву з iddetect-viewport і додає його до тіла, якщо його вже немає (тому ви можете повторно використовувати це прив'язування, не дублюючи ці діви)
  • встановлює поточну точку розриву вікна перегляду на пов'язану, яку можна спостерігати, запитуючи, який з дівок буде видимим
  • оновлює поточну точку розриву вікна перегляду, коли розмір вікна буде змінено

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>


0

Минуло час з початку роботи, але ось моє рішення для цього за допомогою 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();
});
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.