Comment détecter les points d'arrêt réactifs de Twitter Bootstrap 3 à l'aide de JavaScript?

139

Actuellement , Twitter Bootstrap 3 a les points d'arrêt réactifs suivants: 768px, 992px et 1200px, représentant respectivement des appareils petits, moyens et grands.

Comment puis-je détecter ces points d'arrêt à l'aide de JavaScript?

Je souhaite écouter avec JavaScript tous les événements liés déclenchés lorsque l'écran change. Et pour pouvoir détecter si l'écran est destiné aux appareils petits, moyens ou grands.

Y a-t-il quelque chose déjà fait? Quelles sont vos suggestions?

Rubens Mariuzzo
la source
Vous pouvez utiliser IntersectionObserver pour détecter quand une <div class="d-none d-?-block"></div>visibilité change (insérez votre point d'arrêt souhaité). Ces classes CSS sont pour Bootstrap 4 ... utilisent tout ce qui fonctionne dans Bootstrap 3. Beaucoup plus performant que d'écouter l'événement de redimensionnement de la fenêtre.
Matt Thomas

Réponses:

241

Edit: Cette bibliothèque est maintenant disponible via Bower et NPM. Voir le dépôt github pour plus de détails.

RÉPONSE MIS À JOUR:

Avertissement: je suis l'auteur.

Voici quelques choses que vous pouvez faire en utilisant la dernière version (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);

Depuis la version 2.3.0, vous n'avez pas besoin des quatre <div>éléments mentionnés ci-dessous.


RÉPONSE ORIGINALE:

Je ne pense pas que vous ayez besoin d'un énorme script ou d'une bibliothèque pour cela. C'est une tâche assez simple.

Insérez les éléments suivants juste avant </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>

Ces 4 divs vous permettent de vérifier le point d'arrêt actuellement actif. Pour une détection JS facile, utilisez la fonction suivante:

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

Maintenant, pour effectuer une certaine action uniquement sur le plus petit point d'arrêt que vous pourriez utiliser:

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

Détecter les changements une fois que le DOM est prêt est également assez simple. Tout ce dont vous avez besoin est un écouteur de redimensionnement de fenêtre léger comme celui-ci:

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

Une fois que vous en êtes équipé, vous pouvez commencer à écouter les changements et exécuter des fonctions spécifiques aux points d'arrêt comme ceci:

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

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

    }, 300, fullDateString.getTime())
});
Maciej Gurban
la source
3
Ça ne marche pas pour moi. viewport.current () renvoie toujours «non reconnu». Est-ce que je fais quelque chose de mal?
starbugs
Avez-vous un violon? Edit: Serait-il possible que vous incluiez vos scripts, y compris RBT dans la section head, au lieu du body? Cela empêcherait l'ajout de div de visibilité au corps, cassant ainsi la fonctionnalité.
Maciej Gurban
@MaciejGurban Je ne peux pas le faire fonctionner aussi. J'utilise Rails 4.2. J'inclus bootstrap dans ma tête mais votre script dans le corps, mais il continue de dire non reconnu. Ok mon problème j'ai tout ajouté dans le corps. Mais est-ce vraiment nécessaire?
Dennis
Encore une fois, il est difficile de dire le problème sans un violon ou un exemple de code. Vous pouvez poser une question à ce sujet sur SO et la référencer ici, ou ouvrir un problème sur github. Avez-vous suivi l'ordre d'inclusion de toutes les pièces tel qu'il est sur CodePen ? Seule cette fonction ne fonctionne pas? Le problème pourrait-il être comme celui-ci ?
Maciej Gurban
1
Comment cela pourrait-il être utilisé avec bootstrap 4?
Calonthar
64

Si vous n'avez pas de besoins spécifiques, vous pouvez simplement le faire:

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
}

Edit: Je ne vois pas pourquoi vous devriez utiliser une autre bibliothèque js alors que vous pouvez le faire uniquement avec jQuery déjà inclus dans votre projet Bootstrap.

mtt
la source
Merci, pouvez-vous également fournir l'auditeur pour tous les événements qui déclenchent un changement de dimension à l'écran?
Rubens Mariuzzo
Je ne pense pas qu'il y ait des événements sur le changement de dimension de l'écran. Tout ce qui concerne la dimension de l'écran (requêtes multimédias) se trouve dans la feuille de style.
mtt le
2
Je le sais, je cherche juste un comportement similaire dans JS. En fait, écoutez le changement de dimension de l'écran avec: $(window).bind('resize')... mais il y a d'autres événements liés à l'orientation de l'écran mobile qui ont un impact sur la dimension de l'écran.
Rubens Mariuzzo le
L'orientation de l'appareil est toujours une fonctionnalité expérimentale: developer.mozilla.org/en-US/docs/Web/API/DeviceOrientationEvent Je vous suggère d'utiliser.on('resize')
mtt
1
J'ai entendu parler de cas où cette façon de détecter l'état pose des problèmes. Il est préférable d'aller avec quelque chose qui vérifie les éléments d'aide visibles à mon humble avis - juste pour être à l'abri de tous les cas d'angle.
Manuel Arwed Schmidt
11

Avez-vous jeté un œil à Response.js? Il est conçu pour ce genre de chose. Combinez Response.band et 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
    }
});
Mousius
la source
Bibliothèque intéressante, même si elle n'a pas été conçue avec Twitter Bootstrap 3 à l'esprit. Quoi qu'il en soit, on dirait qu'il peut être facilement adapté dans TWBS3.
Rubens Mariuzzo
11

Vous pouvez utiliser la taille de la fenêtre et coder en dur les points d'arrêt. Utilisation angulaire:

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';
                }
            }
        };
    });
srlm
la source
J'aime cette réponse. Aucune autre bibliothèque (pas même jQuery) requise.
dprothero le
11

Détecter le point d'arrêt réactif de Twitter Bootstrap 4.1.x à l'aide de JavaScript

Le Bootstrap v.4.0.0 (et la dernière version Bootstrap 4.1.x ) a présenté les mises à jour les options de grille , de sorte que le vieux concept de la détection ne peut pas être appliqué directement (voir les instructions de migration ):

  • Ajout d'un nouveau smniveau de grille ci-dessous 768pxpour un contrôle plus granulaire. Nous avons maintenant xs, sm, md, lget xl;
  • xs les classes de grille ont été modifiées pour ne pas nécessiter l'infixe.

J'ai écrit la petite fonction utilitaire qui respecte un nom de classe de grille mis à jour et un nouveau niveau de grille:

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

Détecter le point d'arrêt réactif de Bootstrap v4-beta à l'aide de JavaScript

Le v4-alpha Bootstrap et Bootstrap v4 bêta ont une approche différente sur des points d' arrêt de la grille, voici donc le chemin de l' héritage d'atteindre le même:

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

Je pense que ce serait utile, car il est facile à intégrer à n'importe quel projet. Il utilise des classes d'affichage natives réactives du Bootstrap lui-même.

Autre côté
la source
7

Voici ma propre solution simple:

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'));
}
hckr
la source
5

Il est préférable d' utiliser cette approche avec Response.js . Response.resize se déclenche à chaque redimensionnement de fenêtre où le croisement ne sera déclenché que si le point d'arrêt est modifié

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');
});
berkayunal
la source
4

Il ne devrait y avoir aucun problème avec une implémentation manuelle comme celle mentionnée par @oozic.

Voici quelques bibliothèques que vous pouvez consulter:

  • Response.js - plugin jQuery - utilise des attributs de données html et possède également une API js.
  • enquire.js - enquire.js est une bibliothèque JavaScript légère et pure pour répondre aux requêtes multimédias CSS
  • SimpleStateManager - un gestionnaire d'état javascript pour les sites Web réactifs . Il est construit pour être léger, n'a pas de dépendances.

Notez que ces bibliothèques sont conçues pour fonctionner indépendamment du bootstrap, de la fondation, etc. Vous pouvez configurer vos propres points d'arrêt et vous amuser.

Matias
la source
3
Enquire.js semble prometteur.
Rubens Mariuzzo
4

Vous voudrez peut-être l'ajouter à votre projet d'amorçage pour vérifier visuellement le point d'arrêt actif

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

Voici le BOOTPLY

effe
la source
4

S'appuyant sur la réponse de Maciej Gurban (ce qui est fantastique ... si vous aimez ça, votez simplement sa réponse). Si vous créez un service à interroger, vous pouvez renvoyer le service actuellement actif avec la configuration ci-dessous. Cela pourrait remplacer entièrement d'autres bibliothèques de détection de points d'arrêt (comme enquire.js si vous insérez certains événements). Notez que j'ai ajouté un conteneur avec un ID aux éléments DOM pour accélérer la traversée du 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, mais c'est facilement convertible)

# 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;
    }
  };
});
Calcul
la source
3

Pourquoi ne pas simplement utiliser jQuery pour détecter la largeur css actuelle de la classe de conteneur bootstrap?

c'est à dire..

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

Vous pouvez également utiliser $ (window) .resize () pour empêcher votre mise en page de «salir le lit» si quelqu'un redimensionne la fenêtre du navigateur.

Mark Williams
la source
3

Au lieu d'insérer ce qui suit plusieurs fois dans chaque page ...

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

Utilisez simplement JavaScript pour l'insérer dynamiquement dans chaque page (notez que je l'ai mis à jour pour fonctionner avec Bootstrap 3 avec .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");
}
Phillip Quinlan
la source
2

Je n'ai pas assez de points de réputation à commenter, mais pour ceux qui rencontrent des problèmes pour être «non reconnus» lorsqu'ils essaient d'utiliser le ResponsiveToolKit de Maciej Gurban, j'obtiens également cette erreur jusqu'à ce que je remarque que Maciej fait référence à la boîte à outils du bas de la page page dans son CodePen

J'ai essayé de faire ça et tout à coup ça a marché! Alors, utilisez le ResponsiveToolkit mais mettez vos liens en bas de page:

Je ne sais pas pourquoi cela fait une différence, mais c'est le cas.

Michael Ackary
la source
2

Voici une autre façon de détecter la fenêtre courante sans mettre les numéros de taille de la fenêtre dans votre javascript.

Voir les extraits de code CSS et javascript ici: https://gist.github.com/steveh80/288a9a8bd4c3de16d799

Après avoir ajouté ces extraits à vos fichiers css et javascript, vous pouvez détecter la fenêtre d'affichage actuelle comme suit:

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

Si vous souhaitez détecter une plage de fenêtres, utilisez-la comme ceci

viewport.isEqualOrGreaterThan('sm') // returns true for sm, md and lg
steveh80
la source
2

Le CSS de Bootstrap pour la .containerclasse ressemble à ça:

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

Cela signifie donc que nous pouvons compter en toute sécurité jQuery('.container').css('width')pour détecter les points d'arrêt sans les inconvénients de se fier jQuery(window).width().

Nous pouvons écrire une fonction comme celle-ci:

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

Et puis testez-le comme

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

    detectBreakpoint();
});
FlavioEscobar
la source
Cela ne fonctionnera qu'aux largeurs spécifiées; tout ce qui se trouve entre les deux échouera. Il serait peut-être préférable de: Premièrement, parseInt sur cssWidth var cssWidth = parseInt( jQuery('.container').css('width') ); Deuxièmement, utilisez des plages 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

Utilisez CSS :beforeet contentpropriété pour imprimer l'état du point d'arrêt dans le<span id="breakpoint-js"> afin que le JavaScript n'ait qu'à lire ces données pour les transformer en variable à utiliser dans votre fonction.

(exécutez l'extrait pour voir l'exemple)

REMARQUE: j'ai ajouté quelques lignes de CSS pour utiliser le <span>comme indicateur rouge dans le coin supérieur de mon navigateur. Assurez-vous simplement de le réactiver display:none;avant de publier vos contenus.

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

MartinDubeNet
la source
1

J'ai créé une méthode native jQuery pour la détection de la taille de l'écran Twitter Bootstrap. Voici:

// 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 comme exemple plein écran: https://jsfiddle.net/pstepniewski/7dz6ubus/embedded/result/

Piotr Stępniewski
la source
1

Pour toute personne intéressée par cela, j'ai écrit une détection de point d'arrêt basée sur des points d'arrêt CSS en utilisant TypeScript et Observables. il n'est pas très difficile d'en faire ES6, si vous supprimez les types. Dans mon exemple, j'utilise Sass, mais il est également facile de le supprimer.

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

Manuscrit:

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

J'espère que cela aide quelqu'un.

Stefan Jelner
la source
1

Bootstrap4 avec jQuery, solution simplifiée

<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>
Alex R
la source
1

Je n'étais pas vraiment satisfait des réponses données, qui me paraissent trop compliquées à utiliser, j'ai donc rédigé ma propre solution. Cependant, pour le moment, cela repose sur le trait de soulignement / lodash pour fonctionner.

https://github.com/LeShrimp/GridSizeEvents

Vous pouvez l'utiliser comme ceci:

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

Cela fonctionne immédiatement pour Bootstrap 3, car les points d'arrêt sont codés en dur à 768px, 992px et 1200px. Pour les autres versions, vous pouvez facilement adapter le code.

En interne, cela utilise matchMedia () et devrait donc garantir de produire des résultats synchronisés avec Bootstrap.

MaximeW
la source
1

Peut-être que cela aidera certains d'entre vous, mais il existe un plugin qui vous aide à détecter sur quel point d'arrêt Bootstrap v4 actuel vous voyez: https://www.npmjs.com/package/bs-breakpoints

Simple à utiliser (peut être utilisé avec ou sans jQuery):

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

  $(window).on('new.bs.breakpoint', function (event) {
    console.warn(event.breakpoint)
  })
})
Johann-S
la source
1

Voici ma solution (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>
Antonio Petricca
la source
0

Pour tous ceux qui utilisent knockout.js , je voulais des propriétés observables knockout.js qui me diraient quand les points d'arrêt sont atteints. J'ai choisi d'utiliser le support de Modernizr pour les requêtes multimédias de style css afin que les nombres correspondent aux définitions de bootstrap, et pour bénéficier des avantages de compatibilité de modernizr. Mon modèle de vue knockout est le suivant:

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();
};
rogersillito
la source
0

Voici un bon moyen de le détecter (peut-être drôle, mais fonctionne) et vous pouvez utiliser l'élément nécessaire pour que le code soit clair:

Exemple: css:

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

et dans le document par jQuery:

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

bien sûr, la propriété css est any.

Świeżu
la source
0

Puisque bootstrap 4 sera bientôt disponible, j'ai pensé partager une fonction qui le prend en charge (xl est maintenant une chose) et effectue un jQuery minimal pour faire le travail.

/**
 * 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;
}
carcus88
la source
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' : '');
};

ou minifié

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

Vache patriotique
la source
0

Si vous utilisez Knockout , vous pouvez utiliser la liaison personnalisée suivante pour lier le point d'arrêt de la fenêtre actuelle (xs, sm, md ou lg) à une observable dans votre modèle. La reliure ...

  • enveloppe le 4 divsavec visible-??classe dans un div avec iddetect-viewport et l'ajoute au corps s'il n'existe pas déjà (vous pouvez donc réutiliser cette liaison sans dupliquer ces divs)
  • définit le point d'arrêt de la fenêtre courante sur l'observable lié en demandant laquelle des divs est visible
  • met à jour le point d'arrêt de la fenêtre actuelle lorsque la fenêtre est redimensionnée

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>

Philip Bijker
la source
0

Cela fait un moment depuis l'OP, mais voici ma solution pour cela en utilisant Bootstrap 3. Dans mon cas d'utilisation, je ne ciblais que les lignes, mais la même chose pourrait être appliquée au conteneur, etc.

Changez simplement .row à ce que vous voulez.

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