Come rilevare i punti di interruzione reattivi di Twitter Bootstrap 3 utilizzando JavaScript?


139

Attualmente , Bootstrap 3 di Twitter ha i seguenti breakpoint reattivi: 768px, 992px e 1200px, che rappresentano rispettivamente i dispositivi piccoli, medi e grandi.

Come posso rilevare questi punti di interruzione usando JavaScript?

Vorrei ascoltare con JavaScript tutti gli eventi correlati attivati ​​quando cambia lo schermo. E per essere in grado di rilevare se lo schermo è per dispositivi piccoli, medi o grandi.

C'è qualcosa di già fatto? Quali sono i tuoi suggerimenti?


È possibile utilizzare IntersectionObserver per rilevare quando <div class="d-none d-?-block"></div>cambia la visibilità (inserire il punto di interruzione desiderato). Queste classi CSS sono per Bootstrap 4 ... usano tutto ciò che funziona in Bootstrap 3. Molto più performante dell'ascolto dell'evento di ridimensionamento della finestra.
Matt Thomas,

Risposte:


241

Modifica: questa libreria è ora disponibile tramite Bower e NPM. Vedi repo github per i dettagli.

RISPOSTA AGGIORNATA:

Disclaimer: sono l'autore.

Ecco alcune cose che puoi fare usando l'ultima versione (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);

A partire dalla versione 2.3.0, non sono necessari i quattro <div>elementi indicati di seguito.


RISPOSTA ORIGINALE:

Non credo che tu abbia bisogno di grandi sceneggiature o librerie per questo. È un compito abbastanza semplice.

Inserisci i seguenti elementi appena prima </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>

Queste 4 div consentono di verificare il punto di interruzione attualmente attivo. Per un facile rilevamento JS, utilizzare la seguente funzione:

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

Ora per eseguire una determinata azione solo sul punto di interruzione più piccolo è possibile utilizzare:

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

Anche il rilevamento delle modifiche dopo il DOM pronto è abbastanza semplice. Tutto ciò che serve è un ascoltatore di ridimensionamento della finestra leggero come questo:

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

Una volta che ne sei equipaggiato, puoi iniziare ad ascoltare le modifiche ed eseguire funzioni specifiche del breakpoint in questo modo:

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

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

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

3
Non funziona per me. viewport.current () restituisce sempre "non riconosciuto". Sto facendo qualcosa di sbagliato?
Starbugs,

Hai un violino? Modifica: potrebbe essere che includi i tuoi script, incluso RBT nella sezione head, anziché body? Ciò impedirebbe l'aggiunta di div di visibilità al corpo, interrompendo così la funzionalità.
Maciej Gurban,

@MaciejGurban Non riesco a farlo funzionare anche. Sto usando Rails 4.2. Sto includendo bootstrap nella mia testa ma la tua sceneggiatura nel corpo, ma continua a dire non riconosciuta. Ok il mio problema ho aggiunto tutto nel corpo. Ma è davvero necessario?
Dennis,

Ancora una volta, è difficile capire il problema senza un violino o un codice di esempio. Puoi fare una domanda al riguardo su SO e fare riferimento qui, oppure aprire un problema su Github. Hai seguito l'ordine di includere tutte le parti in CodePen ? Solo quella funzione non funziona? Il problema potrebbe essere come questo ?
Maciej Gurban,

1
Come potrebbe essere usato con bootstrap 4?
Calonthar,

64

Se non hai esigenze specifiche, puoi semplicemente fare questo:

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
}

Modifica: non vedo perché dovresti usare un'altra libreria js quando puoi farlo solo con jQuery già incluso nel tuo progetto Bootstrap.


Grazie, puoi anche fornire l'ascoltatore per tutti gli eventi che si attivano al cambio della dimensione dello schermo?
Rubens Mariuzzo,

Non penso che ci siano eventi sul cambiamento delle dimensioni dello schermo. Tutto ciò che riguarda la dimensione dello schermo (media query) è nel foglio di stile.
mtt

2
Lo so, sto solo cercando un comportamento simile in JS. In realtà ascolta il cambiamento della dimensione dello schermo con: $(window).bind('resize')... ma ci sono altri eventi relativi all'orientamento dello schermo mobile che influiscono sulla dimensione dello schermo.
Rubens Mariuzzo,

L'orientamento del dispositivo è ancora una funzionalità sperimentale: developer.mozilla.org/en-US/docs/Web/API/DeviceOrientationEvent Ti suggerisco di usare.on('resize')
mtt

1
Ho sentito parlare di casi in cui questo modo di rilevare lo stato causa problemi. È meglio andare con qualcosa che controlla l'imho degli elementi di supporto visibili - solo per essere al sicuro da qualsiasi caso d'angolo.
Manuel Arwed Schmidt,

11

Hai dato un'occhiata a Response.js? È progettato per questo tipo di cose. Combina Response.band e 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
    }
});

Biblioteca interessante, anche se non è stata progettata pensando a Twitter Bootstrap 3. Ad ogni modo, sembra che possa essere facilmente adattato in TWBS3.
Rubens Mariuzzo,

11

È possibile utilizzare la dimensione della finestra e codificare i punti di interruzione. Utilizzando angolare:

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

Mi piace questa risposta. Non sono necessarie altre librerie (nemmeno jQuery).
dprothero,

11

Rileva il breakpoint reattivo di Twitter Bootstrap 4.1.x utilizzando JavaScript

Il v.4.0.0 Bootstrap (e l'ultima versione Bootstrap 4.1.x ) ha introdotto la versione aggiornata opzioni della griglia , in modo che il vecchio concetto su rilevazione non può essere applicato direttamente (vedi le istruzioni di migrazione ):

  • Aggiunto un nuovo smlivello di griglia in basso 768pxper un controllo più granulare. Ora abbiamo xs, sm, md, lg, e xl;
  • xs le classi della griglia sono state modificate per non richiedere l'infix.

Ho scritto la piccola funzione di utilità che rispetta i nomi di una classe di griglia aggiornata e un nuovo livello di griglia:

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

Rileva breakpoint reattivo di Bootstrap v4-beta utilizzando JavaScript

Il Bootstrap v4-alfa e Bootstrap v4-beta avevano approccio diverso sul breakpoint della griglia, quindi ecco il modo eredità di raggiungere lo stesso:

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

Penso che sarebbe utile, in quanto è facile da integrare in qualsiasi progetto. Utilizza classi di visualizzazione reattive native del Bootstrap stesso.


7

Ecco la mia semplice soluzione:

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

L'uso di questo approccio con Response.js è migliore. Trigger Response.resize su ogni ridimensionamento della finestra in cui il crossover verrà attivato solo se il punto di interruzione viene modificato

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

Non ci dovrebbero essere problemi con alcune implementazioni manuali come quella menzionata da @oozic.

Ecco un paio di librerie a cui potresti dare un'occhiata:

  • Response.js - plugin jQuery - fa uso di attributi di dati html e ha anche un js api.
  • enquire.js - enquire.js è una libreria JavaScript leggera e pura per rispondere alle query multimediali CSS
  • SimpleStateManager - un gestore di stato javascript per siti Web responsive. È costruito per essere leggero, non ha dipendenze.

Nota che queste librerie sono progettate per funzionare indipendentemente da bootstrap, fondotinta, ecc. Puoi configurare i tuoi punti di interruzione e divertirti.


3
Enquire.js sembra promettente.
Rubens Mariuzzo,

4

Potresti voler aggiungere questo al tuo progetto bootstrap per controllare visivamente il punto di interruzione attivo

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

Ecco il BOOTPLY


4

Basandosi sulla risposta di Maciej Gurban (il che è fantastico ... se ti piace, per favore, vota solo la sua risposta). Se stai creando un servizio per eseguire una query, puoi restituire il servizio attualmente attivo con l'impostazione di seguito. Ciò potrebbe sostituire completamente altre librerie di rilevamento dei punti di interruzione (come enquire.js se si inseriscono alcuni eventi). Nota che ho aggiunto un contenitore con un ID agli elementi DOM per velocizzare l'attraversamento del 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, ma questo è facilmente convertibile)

# 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

Perché non usare semplicemente jQuery per rilevare la larghezza attuale dei css della classe del contenitore bootstrap?

cioè ..

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

Puoi anche usare $ (window) .resize () per impedire al tuo layout di "sporcare il letto" se qualcuno ridimensiona la finestra del browser.


3

Invece di inserire più volte il seguito in ogni pagina ...

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

Usa JavaScript per inserirlo dinamicamente in ogni pagina (nota che l'ho aggiornato per funzionare con Bootstrap 3 con .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

Non ho abbastanza punti reputazione da commentare, ma per coloro che hanno problemi a diventare "non riconosciuto" quando provano a utilizzare ResponsiveToolKit di Maciej Gurban, ho riscontrato anche quell'errore fino a quando non ho notato che Maciej fa effettivamente riferimento al toolkit dal fondo del pagina nella sua CodePen

Ho provato a farlo e all'improvviso ha funzionato! Quindi, usa ResponsiveToolkit ma metti i tuoi collegamenti in fondo alla pagina:

Non so perché faccia la differenza ma lo fa.


2

Ecco un altro modo per rilevare la finestra corrente senza inserire i numeri delle dimensioni della finestra nel tuo javascript.

Vedi i frammenti CSS e JavaScript qui: https://gist.github.com/steveh80/288a9a8bd4c3de16d799

Dopo aver aggiunto quegli snippet ai tuoi file css e javascript puoi rilevare l'attuale viewport in questo modo:

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

Se si desidera rilevare un intervallo di viewport utilizzarlo in questo modo

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

2

Il CSS di Bootstrap per la .containerclasse è simile al seguente:

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

Quindi questo significa che possiamo fare affidamento in modo sicuro jQuery('.container').css('width')per rilevare i punti di interruzione senza gli svantaggi di fare affidamento jQuery(window).width().

Possiamo scrivere una funzione come questa:

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

E poi provalo come

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

    detectBreakpoint();
});

Funzionerà solo con le larghezze specificate; qualsiasi cosa nel mezzo fallirà. Potrebbe essere meglio: Primo, analizza su cssWidth var cssWidth = parseInt( jQuery('.container').css('width') ); Secondo, usa gli intervalli 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

Usa CSS :beforee la contentproprietà per stampare lo stato del punto di interruzione nel <span id="breakpoint-js">modo in cui JavaScript deve solo leggere questi dati per trasformarlo in una variabile da utilizzare all'interno della tua funzione.

(esegui lo snippet per vedere l'esempio)

NOTA: ho aggiunto alcune righe di CSS per utilizzare la <span>bandiera rossa nell'angolo superiore del browser. Assicurati di ripristinarlo nuovamente display:none;prima di rendere pubbliche le tue cose.

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

Ho creato un metodo nativo jQuery per il rilevamento della dimensione dello schermo Twitter Bootstrap. Qui è:

// 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 come esempio a schermo intero: https://jsfiddle.net/pstepniewski/7dz6ubus/embedded/result/


1

Per chiunque sia interessato a questo, ho scritto un rilevamento di breakpoint basato su breakpoint CSS usando TypeScript e Observables. non è molto difficile ricavarne ES6 se si rimuovono i tipi. Nel mio esempio uso Sass, ma è anche facile rimuoverlo.

Ecco il mio 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';
  }
}

Dattiloscritto:

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

Spero che questo aiuti qualcuno.


1

Bootstrap4 con jQuery, soluzione semplificata

<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

Non ero davvero soddisfatto delle risposte fornite, che mi sembrano troppo complicate da usare, quindi ho scritto la mia soluzione. Tuttavia, per il momento questo si basa sul trattino basso / lodash per funzionare.

https://github.com/LeShrimp/GridSizeEvents

Puoi usarlo in questo modo:

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

Questo funziona in modo predefinito per Bootstrap 3, poiché i punti di interruzione sono codificati a 768 px, 992 px e 1200 px. Per altre versioni potresti facilmente adattare il codice.

Internamente utilizza matchMedia () e dovrebbe quindi garantire di produrre risultati sincronizzati con Bootstrap.


1

Forse aiuterà alcuni di voi, ma esiste un plug-in che consente di rilevare su quale breakpoint corrente Bootstrap v4 viene visualizzato: https://www.npmjs.com/package/bs-breakpoints

Semplice da usare (può essere utilizzato con o senza jQuery):

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

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

1

Ecco la mia soluzione (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

Per chiunque utilizzi knockout.js , volevo alcune proprietà osservabili knockout.js che mi dicessero quando venivano colpiti i punti di interruzione. Ho scelto di utilizzare il supporto di Modernizr per le query multimediali in stile CSS in modo che i numeri corrispondessero alle definizioni bootstrap e per ottenere i vantaggi di compatibilità di modernizr. Il mio modello di visualizzazione a eliminazione diretta è il seguente:

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

Ecco un buon modo per rilevarlo (forse divertente, ma funziona) e puoi usare l'elemento necessario in modo che il codice sia chiaro:

Esempio: css:

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

e nel documento di jQuery:

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

ovviamente la proprietà css è any.


0

Poiché bootstrap 4 uscirà presto, ho pensato di condividere una funzione che lo supporta (xl ora è una cosa) ed esegue jQuery minimale per completare il lavoro.

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

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

o minimizzato

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

Se si utilizza Knockout , è possibile utilizzare la seguente associazione personalizzata per associare l'attuale punto di interruzione della vista (xs, sm, md o lg) a un osservabile nel modello. La rilegatura ...

  • racchiude il 4 divscon la visible-??classe in un div con id detect-viewporte lo aggiunge al corpo se non esiste già (quindi è possibile riutilizzare questa associazione senza duplicare questi div)
  • imposta il punto di interruzione della vista corrente sul limite osservabile interrogando quale div è visibile
  • aggiorna il punto di interruzione della finestra corrente quando la finestra viene ridimensionata

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

È passato un po 'di tempo dall'OP, ma ecco la mia soluzione per questo usando Bootstrap 3. Nel mio caso d'uso, stavo prendendo di mira solo le righe, ma lo stesso poteva essere applicato al contenitore, ecc.

Basta cambiare .row per quello che vuoi.

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();
});
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.