web-dev-qa-db-fra.com

Twitter Bootstrap - comment détecter le début des requêtes multimédia

quel est le moyen le plus rapide et le plus facile de déclencher lorsque des requêtes de média bootstrap-responsive.css entrent en action?

aller en action = lorsque vous redimensionnez la fenêtre en largeur de mobile et que le site est modifié en mobile réactif

espérons que la question est claire

21
itsme

En utilisant jQuery, vous pouvez trouver la taille de la fenêtre actuelle et ensuite faire votre travail en conséquence.

$(window).resize(function() {
  if ($(this).width() >= 1280) {
    //do something
  }
  else if ($(this).width() < 1280 && $(this).width()>= 980) {
    //do something
  }
  ...
});

CSS:: Twitter-Bootsrap-layouts

/* Large desktop */
@media (min-width: 1200px) { ... }

/* Portrait tablet to landscape and desktop */
@media (min-width: 768px) and (max-width: 979px) { ... }

/* Landscape phone to portrait tablet */
@media (max-width: 767px) { ... }

/* Landscape phones and down */
@media (max-width: 480px) { ... }
13
softvar

J'ai proposé une approche qui utilise un événement de redimensionnement de la fenêtre, mais qui repose sur les requêtes de média de Twitter Bootstrap sans coder en dur leurs points d'arrêt

<span id="mq-detector">
    <span class="visible-xs"></span>
    <span class="visible-sm"></span>
    <span class="visible-md"></span>
    <span class="visible-lg"></span>
</span>

#mq-detector {
    visibility: hidden;
}

var currMqIdx = undefined;
var mqDetector = $("#mq-detector");
var mqSelectors = [
    mqDetector.find(".visible-xs"),
    mqDetector.find(".visible-sm"),
    mqDetector.find(".visible-md"),
    mqDetector.find(".visible-lg")
];

var checkForResize = function() {
    for (var i = 0; i <= mqSelectors.length; i++) {
        if (mqSelectors[i].is(":visible")) {
            if (currMqIdx != i) {
                currMqIdx = i;
                console.log(mqSelectors[i].attr("class"));
            }
            break;
        }
    }
};

$(window).on('resize', checkForResize);

checkForResize();
26
falsarella

Un problème avec les autres réponses est que l'événement de changement est déclenché TOUS les redimensionnements. Cela peut être très coûteux si votre javascript fait quelque chose d'important.

Le code ci-dessous appelle votre fonction de mise à jour une seule fois, lorsqu'un seuil est franchi.

Pour tester, saisissez votre poignée de taille de fenêtre et faites-la redimensionner rapidement pour voir si le navigateur est indisponible.

<script>
// Global state variable
var winSize = '';

window.onresize = function () {
    var newWinSize = 'xs'; // default value, check for actual size
    if ($(this).width() >= 1200) {
        newWinSize = 'lg';
    } else if ($(this).width() >= 992) {
        newWinSize = 'md';
    } else if ($(this).width() >= 768) {
        newWinSize = 'sm';
    }

    if( newWinSize != winSize ) {
        doSomethingOnSizeChange();
        winSize = newWinSize;
    }
};
</script>
14
Stickley

Cela fonctionne pour moi en combinaison avec Bootstrap 3:

<div id="media-width-detection-element"></div>
<style type="text/css">
    #media-width-detection-element {
        display: none;
        width: 0px;
    }
    @media (min-width: 768px) {
        #media-width-detection-element {
            width: 768px;
        }
    }
    @media (min-width: 992px) {
        #media-width-detection-element {
            width: 992px;
        }
    }
    @media (min-width: 1200px) {
        #media-width-detection-element {
            width: 1200px;
        }
    }
</style>
<script type="text/javascript">
    //<![CDATA[
    function xs() {
        return $("#media-width-detection-element").css("width") === "0px";
    }
    function sm() {
        return $("#media-width-detection-element").css("width") === "768px";
    }
    function md() {
        return $("#media-width-detection-element").css("width") === "992px";
    }
    function lg() {
        return $("#media-width-detection-element").css("width") === "1200px";
    }
    //]]>
</script>

La DIV masquée change de largeur en fonction des paramètres CSS min-width réellement utilisés. Ensuite, mon simple javascript vérifie le courant avec de la DIV.

10
Bjørn Stenfeldt

Excellent conseil, @falsarella!

Pour ceux qui aiment ce genre de chose pour ne pas affecter leur marge réelle, les travaux suivants:

$(function(){
...
var mqClasses = ["visible-xs", "visible-sm", "visible-md", "visible-lg"];
var mq = $("<span id='mqDetector' style='visibility:hidden'></span>").appendTo($("body"));
$.each(mqClasses, function(idx, val) {
    mq.append("<span class='" + val + "'></span>");
});
function checkMQ() {
    var visible = mq.find(":visible").get(0).className;
    return visible.slice(-2);
};

function checkResize(){
    switch(checkMQ){
      case 'xs' : ...; break;
      case 'sm' : ...; break;
     ...
    }
}
$(window).on('resize', checkResize);
checkResize(); //do it once when page loads.
5
bknights

Sur la base de la solution de @ falsarella , la partie js peut être simplifiée pour:

var currMqIdx = undefined;
var checkForResize = function() {    
    currMqIdx = $('#mq-detector span').index($('#mq-detector span:visible'));
};

$(window).on('resize', checkForResize);
checkForResize();

currMqIdx serait une valeur int, comprise entre 0 et 3. Plus currMqIdx est grand, plus le support est large.

1
aGuegu

ce code ajoute une balise body ld , md , sd ou xd class 

     $(function(){

        var device_width_detect = '';

        function device_detec(){
            if ($(this).width() >= 1280) {
                device_width_detect = 'ld';
            }else if ($(this).width() < 1280 && $(this).width()>= 992) {
                device_width_detect = 'md';
            }else if ($(this).width() < 992 && $(this).width()>= 768) {
                device_width_detect = 'sd';
            }else if ($(this).width() < 768) {
                device_width_detect = 'xd';
            }
            $('body').removeClass( "ld md sd xd" ).addClass( device_width_detect );
        }
        device_detec();
        $(window).on('resize', device_detec);

    });
1
user243709

J'ai préparé une bibliothèque très légère pour gérer les événements déclenchés lorsque la largeur de la fenêtre et le point d'arrêt Bootstrap sont modifiés - responsive-breakpoint-tester

var viewport = new ResponsiveTester();

$('body').on('in.screen.xs', function(event, devices) {
    // Code executed when viewport is was changed to xs
});

$('body').on('out.screen.xs', function(event, devices) {
    // Code executed when viewport is no longer xs
});

D'autres fonctionnalités telles que la vérification actuelle des points d'arrêt sont également incluses:

if (viewport.is('xs')) {
    // Executed only on xs breakpoint
}

if (viewport.is('!=xs')) {
    // Executed on all breakpoints that are not equal xs (sm, md, lg)
}

if (viewport.is('<md')) {
    // Executed on breakpoints that are smaller than md (xs, sm)
}

if (viewport.is('<=md')) {
    // Executed on breakpoints that are smaller or equal to md (xs, sm, md)
}

if (viewport.is('>md')) {
    // Executed on breakpoints that are larger than md (lg)
}

Les configurations Bootstrap 4 et Foundation sont supportées, plus d’informations sur le référentiel GitHub

1
patrykgruszka

Plus simple

$(window).on('resize', function () {
  if ($('<div class="visible-lg">').css('display')=='block') {
    // Do something for lg
  }
  // ...
});
0
cmc

voici ma solution pour bootstrap 4, basée sur @falsarella idea

* remarque: utilisez l'option "page entière" ci-dessous pour tester cet extrait, sinon il renverra un type d'écran incorrect, basé sur la taille de l'extrait iframe

/**
 * @returns STRING current screen type like: xs, sm, md, lg or xl
 */
function getScreenType() {

  !function initHelpers() {
    if ($('div.mq-detector').length !== 0) return;
    $('body').append(_mqDetector());
    // helpers
    function _mqDetector() {
      return `
      <div class="mq-detector invisible">
        <div
          class="d-block d-sm-none"
          data-type="xs"></div>
        <div
          class="d-none d-sm-block d-md-none"
          data-type="sm"></div>
        <div
          class="d-none d-md-block d-lg-none"
          data-type="md"></div>
        <div
          class="d-none d-lg-block d-xl-none"
          data-type="lg"></div>
        <div
          class="d-none d-xl-block"
          data-type="xl"></div>
      </div>
      `;
    }
  }();

  // @then

  return $('div.mq-detector').children().filter(':visible').data('type');

}

console.log(getScreenType())
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous">

0
webolizzer

J'ai révisé les codes dans this lien vers Bootstrap 4 pas alpha ou bêta. Codes comme ci-dessous;

    /* **********************************************************
        Detect bootrap 4 media query type
        https://getbootstrap.com/docs/4.0/utilities/display/
   ********************************************************** */


    $("body").append("<div style='visibilty:hidden' class='viewport-check'><span class='d-block d-sm-none'>xs</span><span class='d-none d-sm-block d-md-none'>sm</span><span class='d-none d-md-block d-lg-none'>md</span><span class='d-none d-lg-block d-xl-none'>lg</span><span class='d-none d-xl-block'>xl</span></div>");

    var Bootstrap4MediaQuery = "";

    //> Checks if the span is set to display block via CSS
    function FnDetectMediaQuery(_QsTarget) {
        var _QsTarget = $(_QsTarget).css('display') == 'block';
        return _QsTarget;
    }

    if(FnDetectMediaQuery('.viewport-check .d-block') == true)
    {
        Bootstrap4MediaQuery = "xs";
    }
    else if(FnDetectMediaQuery('.viewport-check .d-sm-block') == true)
    {
        Bootstrap4MediaQuery = "sm";
    }
    else if(FnDetectMediaQuery('.viewport-check .d-md-block') == true)
    {
        Bootstrap4MediaQuery = "md";
    }
    else if(FnDetectMediaQuery('.viewport-check .d-lg-block') == true)
    {
        Bootstrap4MediaQuery = "lg";
    }
    else if(FnDetectMediaQuery('.viewport-check .d-xl-block') == true)
    {
        Bootstrap4MediaQuery = "xl";
    }
    else
    {
        Bootstrap4MediaQuery = "";
    }

    console.log("Bootstrap4MediaQuery: " + Bootstrap4MediaQuery);
0
Kerberos

Vous pouvez utiliser matchMedia et une bibliothèque wrapper enquire.js qui enregistre les requêtes de média et émet des événements quand ils correspondent ou ne correspondent pas.

Usage

Utilisons ces requêtes de support CSS Bootstrap comme exemple tiré de the docs .

/* Extra small devices (phones, less than 768px) */
/* No media query since this is the default in Bootstrap */

/* Small devices (tablets, 768px and up) */
@media (min-width: @screen-sm-min) { ... }

/* Medium devices (desktops, 992px and up) */
@media (min-width: @screen-md-min) { ... }

/* Large devices (large desktops, 1200px and up) */
@media (min-width: @screen-lg-min) { ... }

Pour savoir quand chacune de ces règles est appliquée, utilisez enquire.js pour enregistrer les requêtes sur le support et fournir les fonctions match et unmatch appropriées, comme ci-dessous:

let rules = [
    '(max-width: 768px)',  // extra small devices, default
    '(min-width: 768px)',  // small devices
    '(min-width: 992px)',  // medium devices
    '(min-width: 1200px)'  // large devices
];

for (let rule of rules) {
    enquire.register(rule, {
      match: function() {
        console.log(rule + ' matched');
      },      

      unmatch: function() {
        console.log(rule + ' unmatched');
      } 
    });
}

enquire.js utilise matchMedia qui ne prend en charge que les navigateurs modernes , pas IE9 par exemple. So polyfill sera nécessaire pour les navigateurs existants pour que cela fonctionne. 

Démo

0

J'ai utilisé cela pour coller uniquement la barre de navigation à https://ducttapedanyol.com in bootstrap sur de grands écrans:

if ($(this).width() >= 979) { // Detect screen size
$(document).ready(function () {

    var menu = $('.menu');
    var origOffsetY = menu.offset().top;

    function scroll() {
       if ($(window).scrollTop() >= origOffsetY) {
          $('.menu').addClass('sticky');
          $('.fix').addClass('fix-tall');
       } else {
          $('.menu').removeClass('sticky');
          $('.fix').removeClass('fix-tall');
       }


    }

    document.onscroll = scroll;

});
}
0
Topher