Wie erkenne ich reaktionsfähige Haltepunkte von Twitter Bootstrap 3 mithilfe von JavaScript?

139

Derzeit hat Twitter Bootstrap 3 die folgenden reaktionsfähigen Haltepunkte: 768px, 992px und 1200px, die kleine, mittlere und große Geräte darstellen.

Wie kann ich diese Haltepunkte mithilfe von JavaScript erkennen?

Ich möchte mit JavaScript auf alle verwandten Ereignisse warten, die ausgelöst werden, wenn sich der Bildschirm ändert. Und um erkennen zu können, ob der Bildschirm für kleine, mittlere oder große Geräte geeignet ist.

Ist schon etwas erledigt? Was sind deine Vorschläge?

Rubens Mariuzzo
quelle
Mit IntersectionObserver können Sie erkennen, wenn <div class="d-none d-?-block"></div>sich die Sichtbarkeit ändert (fügen Sie den gewünschten Haltepunkt ein). Diese CSS-Klassen sind für Bootstrap 4 ... verwenden Sie alles, was in Bootstrap 3 funktioniert. Viel leistungsfähiger als das Abhören von Ereignissen zur Größenänderung von Fenstern.
Matt Thomas

Antworten:

241

Bearbeiten: Diese Bibliothek ist jetzt über Bower und NPM verfügbar. Siehe Github Repo für Details.

AKTUALISIERTE ANTWORT:

Haftungsausschluss: Ich bin der Autor.

Hier sind einige Dinge, die Sie mit der neuesten Version (Responsive Bootstrap Toolkit 2.5.0) tun können:

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

Ab Version 2.3.0 benötigen Sie die vier <div>unten genannten Elemente nicht mehr.


URSPRÜNGLICHE ANTWORT:

Ich glaube nicht, dass Sie dafür ein riesiges Skript oder eine Bibliothek brauchen. Es ist eine ziemlich einfache Aufgabe.

Fügen Sie kurz zuvor die folgenden Elemente ein </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>

Mit diesen 4 Divs können Sie nach dem aktuell aktiven Haltepunkt suchen. Verwenden Sie für eine einfache JS-Erkennung die folgende Funktion:

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

Um nun eine bestimmte Aktion nur an dem kleinsten Haltepunkt auszuführen, den Sie verwenden können:

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

Das Erkennen von Änderungen nach der DOM-Bereitschaft ist ebenfalls recht einfach. Alles, was Sie brauchen, ist ein leichtgewichtiger Listener zur Größenänderung von Fenstern wie dieser:

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

Sobald Sie damit ausgestattet sind, können Sie auf Änderungen warten und Haltepunkt-spezifische Funktionen wie folgt ausführen:

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

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

    }, 300, fullDateString.getTime())
});
Maciej Gurban
quelle
3
Funktioniert bei mir nicht viewport.current () liefert immer 'nicht erkannt'. Mache ich etwas falsch?
Starbugs
Hast du eine Geige? Bearbeiten: Könnte es sein, dass Sie Ihre Skripte, einschließlich RBT, im Kopfbereich anstelle von body einfügen? Dies würde verhindern, dass Sichtbarkeits-Divs zum Körper hinzugefügt werden, wodurch die Funktionalität beeinträchtigt wird.
Maciej Gurban
@ MaciejGurban Ich kann es auch nicht zum Laufen bringen. Ich benutze Rails 4.2. Ich füge Bootstrap in meinen Kopf ein, aber dein Skript in den Körper, aber es sagt immer wieder, dass es nicht erkannt wird. Ok mein Problem ich habe alles im Körper hinzugefügt. Aber ist das wirklich nötig?
Dennis
Wieder einmal ist es schwierig, das Problem ohne Geige oder Beispielcode zu erkennen. Sie können eine Frage dazu in SO stellen und hier darauf verweisen oder ein Problem in Github eröffnen. Haben Sie die Reihenfolge befolgt, in der alle Teile in CodePen enthalten sind ? Funktioniert nur diese Funktion nicht? Könnte das Problem wie seine diese ?
Maciej Gurban
1
Wie könnte dies mit Bootstrap 4 verwendet werden?
Calonthar
64

Wenn Sie keine spezifischen Bedürfnisse haben, können Sie dies einfach tun:

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
}

Bearbeiten: Ich verstehe nicht, warum Sie eine andere js-Bibliothek verwenden sollten, wenn Sie dies nur mit jQuery tun können, das bereits in Ihrem Bootstrap-Projekt enthalten ist.

mtt
quelle
Vielen Dank, können Sie den Listener auch für alle Ereignisse bereitstellen, die bei einer Änderung der Bildschirmgröße ausgelöst werden?
Rubens Mariuzzo
Ich glaube nicht, dass es Ereignisse bei der Änderung der Bildschirmgröße gibt. Alles, was mit der Bildschirmdimension (Medienabfragen) zu tun hat, befindet sich im Stylesheet.
mtt
2
Ich weiß das, ich sehe nur ein ähnliches Verhalten in JS. Hören Sie sich die Änderung der Bildschirmgröße tatsächlich an mit: $(window).bind('resize')..., aber es gibt andere Ereignisse für die Ausrichtung des mobilen Bildschirms, die sich auf die Bildschirmgröße auswirken.
Rubens Mariuzzo
Die Geräteorientierung ist immer noch eine experimentelle Funktion: developer.mozilla.org/en-US/docs/Web/API/DeviceOrientationEvent Ich empfehle Ihnen,.on('resize')
mtt
1
Ich habe von Fällen gehört, in denen diese Art der Zustandserkennung Probleme verursacht. Es ist besser, imho nach sichtbaren Hilfselementen zu suchen - nur um vor allen Eckfällen sicher zu sein.
Manuel Arwed Schmidt
11

Haben Sie sich Response.js angesehen? Es ist für solche Dinge konzipiert. Kombinieren Sie Response.band und 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
quelle
Interessante Bibliothek, obwohl sie nicht für Twitter Bootstrap 3 entwickelt wurde. Wie auch immer, es kann leicht in TWBS3 angepasst werden.
Rubens Mariuzzo
11

Sie können die Fenstergröße verwenden und die Haltepunkte fest codieren. Verwenden von Angular:

angular
    .module('components.responsiveDetection', [])
    .factory('ResponsiveDetection', function ($window) {
        return {
            getBreakpoint: function () {
                var w = $window.innerWidth;
                if (w < 768) {
                    return 'xs';
                } else if (w < 992) {
                    return 'sm';
                } else if (w < 1200) {
                    return 'md';
                } else {
                    return 'lg';
                }
            }
        };
    });
srlm
quelle
Ich mag diese Antwort. Keine anderen Bibliotheken (nicht einmal jQuery) erforderlich.
Dprothero
11

Erkennen Sie den reaktionsfähigen Haltepunkt von Twitter Bootstrap 4.1.x mithilfe von JavaScript

Das Bootstrap v.4.0.0 (und die neueste Version Bootstrap 4.1.x ) eingeführt , um die aktualisierten Rasteroptionen , so dass das alte Konzept auf der Erfassung nicht direkt angewandt werden kann (siehe die Migrationsanleitung ):

  • Ein neues hinzugefügt smUnten wurde Rasterebene 768pxfür eine genauere Steuerung . Wir haben jetzt xs, sm, md, lg, und xl;
  • xs Gitterklassen wurden so geändert, dass das Infix nicht erforderlich ist.

Ich habe die kleine Dienstprogrammfunktion geschrieben, die aktualisierte Rasterklassennamen und eine neue Rasterebene berücksichtigt:

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

Ermitteln Sie mithilfe von JavaScript den reaktionsfähigen Haltepunkt von Bootstrap v4-beta

Das Bootstrap v4-alpha und Bootstrap v4-beta anderen Ansatz auf Grid - Stützpunkten hatten, also hier das Erbe Weg , um das gleiche zu erreichen:

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

Ich denke, es wäre nützlich, da es einfach in jedes Projekt zu integrieren ist. Es werden native responsive Anzeigeklassen des Bootstraps selbst verwendet.

Farside
quelle
7

Hier meine eigene einfache Lösung:

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

Die Verwendung dieses Ansatzes mit Response.js ist besser. Response.resize-Trigger in jedem Fenster ändern die Größe, wobei Crossover nur ausgelöst wird, wenn der Haltepunkt geändert wird

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

Bei manuellen Implementierungen wie der von @oozic erwähnten sollte es kein Problem geben.

Hier sind ein paar Bibliotheken, die Sie sich ansehen können:

Beachten Sie, dass diese Bibliotheken unabhängig von Bootstrap, Foundation usw. funktionieren. Sie können Ihre eigenen Haltepunkte konfigurieren und Spaß haben.

Matias
quelle
3
Enquire.js sieht vielversprechend aus.
Rubens Mariuzzo
4

Möglicherweise möchten Sie dies Ihrem Bootstrap-Projekt hinzufügen, um den aktiven Haltepunkt visuell zu überprüfen

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

Hier ist die BOOTPLY

effe
quelle
4

Aufbauend auf der Antwort von Maciej Gurban (was fantastisch ist ... wenn Ihnen das gefällt, stimmen Sie einfach seine Antwort ab). Wenn Sie einen Dienst zum Abfragen erstellen, können Sie den aktuell aktiven Dienst mit dem folgenden Setup zurückgeben. Dies könnte andere Haltepunkterkennungsbibliotheken vollständig ersetzen (wie enquire.js, wenn Sie einige Ereignisse eingeben). Beachten Sie, dass ich den DOM-Elementen einen Container mit einer ID hinzugefügt habe, um die DOM-Durchquerung zu beschleunigen.

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, aber dies ist leicht konvertierbar)

# 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;
    }
  };
});
Stein
quelle
3

Warum nicht einfach jQuery verwenden, um die aktuelle CSS-Breite der Bootstrap-Containerklasse zu ermitteln?

dh ..

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

Sie können auch $ (window) .resize () verwenden, um zu verhindern, dass Ihr Layout das Bett "verschmutzt", wenn jemand die Größe des Browserfensters ändert.

Mark Williams
quelle
3

Anstatt das Folgende mehrmals in jede Seite einzufügen ...

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

Verwenden Sie einfach JavaScript, um es dynamisch in jede Seite einzufügen (beachten Sie, dass ich es aktualisiert habe, um mit Bootstrap 3 zu arbeiten mit .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
quelle
2

Ich habe nicht genügend Reputationspunkte, um Kommentare abzugeben, aber für diejenigen, die Probleme haben, "nicht erkannt" zu werden, wenn sie versuchen, das ResponsiveToolKit von Maciej Gurban zu verwenden, wurde dieser Fehler ebenfalls angezeigt, bis ich bemerkte, dass Maciej tatsächlich auf das Toolkit von unten verweist Seite in seinem CodePen

Ich habe es versucht und plötzlich hat es funktioniert! Verwenden Sie also das ResponsiveToolkit, aber platzieren Sie Ihre Links unten auf der Seite:

Ich weiß nicht, warum es einen Unterschied macht, aber es tut es.

Michael Ackary
quelle
2

Hier ist eine andere Möglichkeit, das aktuelle Ansichtsfenster zu erkennen, ohne die Größen der Ansichtsfenster in Ihr Javascript aufzunehmen.

Siehe CSS- und Javascript-Schnipsel hier: https://gist.github.com/steveh80/288a9a8bd4c3de16d799

Nachdem Sie diese Snippets zu Ihren CSS- und Javascript-Dateien hinzugefügt haben, können Sie das aktuelle Ansichtsfenster folgendermaßen erkennen:

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

Wenn Sie einen Ansichtsfensterbereich erkennen möchten, verwenden Sie ihn wie folgt

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

Das CSS von Bootstrap für die .containerKlasse sieht folgendermaßen aus:

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

Dies bedeutet, dass wir uns sicher darauf verlassen jQuery('.container').css('width')können, Haltepunkte zu erkennen, ohne die Nachteile, auf die wir uns verlassen müssen jQuery(window).width().

Wir können eine Funktion wie diese schreiben:

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

Und dann teste es gerne

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

    detectBreakpoint();
});
FlavioEscobar
quelle
Dies funktioniert nur bei den angegebenen Breiten. alles dazwischen wird scheitern. Es könnte am besten sein: Erstens, parseInt auf cssWidth var cssWidth = parseInt( jQuery('.container').css('width') ); Zweitens, verwenden Sie Bereiche 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

Verwenden Sie CSS :beforeund contentEigenschaft, um den Haltepunktstatus in der zu drucken<span id="breakpoint-js"> sodass das JavaScript diese Daten nur lesen muss, um sie als Variable für Ihre Funktion zu verwenden.

(Führen Sie das Snippet aus, um das Beispiel zu sehen.)

HINWEIS: Ich habe einige Zeilen CSS hinzugefügt, um die <span>als rote Fahne in der oberen Ecke meines Browsers zu verwenden. Stellen Sie einfach sicher, dass Sie es wieder auf schalten, display:none;bevor Sie Ihre Inhalte veröffentlichen.

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

Ich habe eine native jQuery-Methode für die Erkennung der Twitter Bootstrap-Bildschirmgröße erstellt. Hier ist:

// 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 als Vollbildbeispiel: https://jsfiddle.net/pstepniewski/7dz6ubus/embedded/result/

Piotr Stępniewski
quelle
1

Für alle, die daran interessiert sind, habe ich eine Breakpoint-Erkennung basierend auf CSS-Breakpoints mit TypeScript und Observables geschrieben. Es ist nicht sehr schwer, ES6 daraus zu machen, wenn Sie die Typen entfernen. In meinem Beispiel verwende ich Sass, aber es ist auch einfach, dies zu entfernen.

Hier ist meine 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';
  }
}

Typoskript:

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

Ich hoffe das hilft jemandem.

Stefan Jelner
quelle
1

Bootstrap4 mit jQuery, vereinfachte Lösung

<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.
quelle
1

Ich war nicht wirklich zufrieden mit den gegebenen Antworten, die mir zu kompliziert erscheinen, also schrieb ich meine eigene Lösung. Derzeit ist dies jedoch auf Unterstrich / Lodash angewiesen, um funktionieren zu können.

https://github.com/LeShrimp/GridSizeEvents

Sie können es so verwenden:

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

Dies funktioniert sofort für Bootstrap 3, da die Haltepunkte fest auf 768px, 992px und 1200px codiert sind. Für andere Versionen können Sie den Code leicht anpassen.

Intern verwendet dies matchMedia () und sollte daher garantieren, dass Ergebnisse erzielt werden, die mit Bootstrap synchron sind.

MaximeW
quelle
1

Vielleicht hilft es einigen von Ihnen, aber es gibt ein Plugin, mit dem Sie erkennen können, auf welchem ​​aktuellen Bootstrap v4- Haltepunkt Sie sich befinden: https://www.npmjs.com/package/bs-breakpoints

Einfach zu bedienen (kann mit oder ohne jQuery verwendet werden):

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

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

Hier ist meine Lösung (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
quelle
0

Für alle, die knockout.js verwenden , wollte ich einige beobachtbare Eigenschaften von knockout.js , die mir sagen, wann die Haltepunkte erreicht werden. Ich habe mich dafür entschieden, die Unterstützung von Modernizr für Medienabfragen im CSS-Stil zu verwenden, damit die Zahlen mit den Bootstrap-Definitionen übereinstimmen, und die Kompatibilitätsvorteile von modernizr zu nutzen. Mein Knockout-Ansichtsmodell lautet wie folgt:

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

Hier ist ein guter Weg, um es zu erkennen (vielleicht lustig, aber funktioniert) und Sie können das erforderliche Element verwenden, damit der Code klar ist:

Beispiel: css:

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

und im Dokument von jQuery:

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

Natürlich ist CSS-Eigenschaft jede.

Świeżu
quelle
0

Da Bootstrap 4 bald herauskommen wird, dachte ich, ich würde eine Funktion teilen, die es unterstützt (xl ist jetzt eine Sache) und nur minimale jQuery ausführt, um die Arbeit zu erledigen.

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

oder minimiert

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

Patriotische Kühe
quelle
0

Wenn Sie Knockout verwenden , können Sie die folgende benutzerdefinierte Bindung verwenden, um den aktuellen Haltepunkt des Ansichtsfensters (xs, sm, md oder lg) an eine in Ihrem Modell beobachtbare Größe zu binden. Die Bindung...

  • Wraps die 4 divsmit visible-??Klasse in ein Div mit IDdetect-viewport und fügt sie dem Body hinzu, falls sie noch nicht vorhanden ist (Sie können diese Bindung also wiederverwenden, ohne diese Divs zu duplizieren).
  • Setzt den aktuellen Haltepunkt des Ansichtsfensters auf die beobachtbare Grenze, indem abgefragt wird, welcher der Divs sichtbar ist
  • Aktualisiert den aktuellen Haltepunkt des Ansichtsfensters, wenn die Fenstergröße geändert wird

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

Es ist eine Weile her seit dem OP, aber hier ist meine Lösung für dieses Problem mit Bootstrap 3. In meinem Anwendungsfall habe ich nur Zeilen als Ziel ausgewählt, aber das Gleiche könnte auf den Container usw. angewendet werden.

Ändern Sie einfach .row auf das, was Sie wollen.

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
quelle