$(ventana).width() no es lo mismo que media query


Estoy usando Twitter Bootstrap en un proyecto. Además de los estilos de bootstrap predeterminados, también he agregado algunos de mis propios

//My styles
@media (max-width: 767px)
{
    //CSS here
}

También estoy usando jQuery para cambiar el orden de ciertos elementos en la página cuando el ancho de la ventana es menor que 767px.

$(document).load($(window).bind("resize", checkPosition));

function checkPosition()
{
    if($(window).width() < 767)
    {
        $("#body-container .main-content").remove().insertBefore($("#body-container .left-sidebar"));
    } else {
        $("#body-container .main-content").remove().insertAfter($("#body-container .left-sidebar"));
    }
}

El problema que tengo es que el ancho calculado por $(window).width() y el ancho calculado por el CSS no parecen ser los mismos. Cuando $(window).width() devuelve 767 el css calcula el ancho de la ventana como 751 parece ser un 16px diferente.

¿Alguien sabe lo que está causando esto y cómo podría resolver el problema? La gente ha sugerido que el ancho de la barra de desplazamiento no se está teniendo en cuenta y usar $(window).innerWidth() < 751 es el camino a seguir. Sin embargo, idealmente quiero encontrar una solución que calcule el ancho de la barra de desplazamiento y que sea consistente con mi consulta de medios (por ejemplo, donde ambas condiciones se comparan con el valor 767). Porque seguramente no todos los navegadores tendrán un ancho de barra de desplazamiento de 16px?

Author: Pattle, 2013-10-10

14 answers

Si no tiene que soportar IE9, puede usar window.matchMedia() (MDN documentation ).

function checkPosition() {
    if (window.matchMedia('(max-width: 767px)').matches) {
        //...
    } else {
        //...
    }
}

window.matchMedia es totalmente consistente con las consultas de medios CSS y el soporte del navegador es bastante bueno: http://caniuse.com/#feat=matchmedia

ACTUALIZACIÓN:

Si tiene que soportar más navegadores, puede usar el método mq de de Modernizr, admite todos los navegadores que entienden las consultas de medios en CSS.

if (Modernizr.mq('(max-width: 767px)')) {
    //...
} else {
    //...
}
 253
Author: ausi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-03-31 07:45:14

Compruebe una regla CSS que cambia la consulta de medios. Esto está garantizado para trabajar siempre.

Http://www.fourfront.us/blog/jquery-window-width-and-media-queries

HTML:

<body>
    ...
    <div id="mobile-indicator"></div>
</body>

Javascript:

function isMobileWidth() {
    return $('#mobile-indicator').is(':visible');
}

CSS:

#mobile-indicator {
    display: none;
}

@media (max-width: 767px) {
    #mobile-indicator {
        display: block;
    }
}
 152
Author: NateS,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-15 13:12:38

Puede ser debido a scrollbar, use innerWidth en lugar de width como

if($(window).innerWidth() <= 751) {
   $("#body-container .main-content").remove()
                                .insertBefore($("#body-container .left-sidebar"));
} else {
   $("#body-container .main-content").remove()
                                .insertAfter($("#body-container .left-sidebar"));
}

También puedes obtener el viewport como

function viewport() {
    var e = window, a = 'inner';
    if (!('innerWidth' in window )) {
        a = 'client';
        e = document.documentElement || document.body;
    }
    return { width : e[ a+'Width' ] , height : e[ a+'Height' ] };
}

Código Anterior Fuente

 32
Author: Rohan Kumar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-03-25 11:03:49

Sí, eso se debe a la barra de desplazamiento. Fuente de la respuesta correcta: introduzca aquí la descripción del enlace

function viewport() {
    var e = window, a = 'inner';
    if (!('innerWidth' in window )) {
        a = 'client';
        e = document.documentElement || document.body;
    }
    return { width : e[ a+'Width' ] , height : e[ a+'Height' ] };
}
 9
Author: Rantiev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-19 14:26:51

Es quizás una mejor práctica no JS-scope el ancho del documento, sino algún tipo de cambio realizado por css @media query. Con este método puede estar seguro de que la función jQuery y el cambio css ocurren al mismo tiempo.

Css:

#isthin {
    display: inline-block;
    content: '';
    width: 1px;
    height: 1px;
    overflow: hidden;
}

@media only screen and (max-width: 990px) {
    #isthin {
        display: none;
    }
}

Jquery:

$(window).ready(function(){
    isntMobile = $('#isthin').is(":visible");
    ...
});

$(window).resize(function(){
    isntMobile = $('#isthin').is(":visible");
    ...
});
 5
Author: gramgram,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-03-25 19:09:10

Me estaba enfrentando al mismo problema recientemente - también con Bootstrap 3.

Ni $.width () nor $.innerWidth () funcionará para usted.

La mejor solución que se me ocurrió - y está específicamente diseñada para BS3 -
es comprobar el ancho de un elemento .container.

Como probablemente sabes cómo funciona el elemento .container ,
es el único elemento que le dará el ancho actual establecido por las reglas css de BS.

Así que va algo como

bsContainerWidth = $("body").find('.container').width()
if (bsContainerWidth <= 768)
    console.log("mobile");
else if (bsContainerWidth <= 950)
    console.log("small");
else if (bsContainerWidth <= 1170)
    console.log("medium");
else
    console.log("large");
 3
Author: user3041539,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-03-27 09:57:25

Use

Ventana.innerWidth

Esto resolvió mi problema

 3
Author: user4451021,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-13 21:23:50

Aquí hay una alternativa a los métodos mencionados anteriormente que se basan en cambiar algo a través de CSS y leerlo a través de Javascript. Este método no necesita window.matchMedia o Modernizr. Tampoco necesita ningún elemento HTML adicional. Funciona mediante el uso de un pseudo-elemento HTML para 'almacenar' información de punto de interrupción:

body:after {
  visibility: hidden;
  height: 0;
  font-size: 0;
}

@media (min-width: 20em) {
  body:after {
    content: "mobile";
  }
}

@media (min-width: 48em) {
  body:after {
    content: "tablet";
  }
}

@media (min-width: 64em) {
  body:after {
    content: "desktop";
  }
}

Usé body como ejemplo, puede usar cualquier elemento HTML para esto. Puede agregar cualquier cadena o número que desee en el content del pseudo-elemento. No tiene que ser 'móvil' y así en.

Ahora podemos leer esta información de Javascript de la siguiente manera:

var breakpoint = window.getComputedStyle(document.querySelector('body'), ':after').getPropertyValue('content').replace(/"/g,'');

if (breakpoint === 'mobile') {
    doSomething();
}

De esta manera siempre estamos seguros de que la información del punto de interrupción es correcta, ya que viene directamente de CSS y no tenemos que molestarnos con obtener el ancho de pantalla correcto a través de Javascript.

 3
Author: dschenk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-19 13:54:38

Javascript proporciona más de un método para comprobar el ancho de la ventana. Como notaste, innerWidth no incluye el ancho de la barra de herramientas, y los anchos de la barra de herramientas diferirán entre los sistemas. También está la opción outerWidth, que incluirá el ancho de la barra de herramientas. El Mozilla Javascript API establece:

Ventana.outerWidth obtiene el ancho del exterior de la ventana del navegador. Representa el ancho de toda la ventana del navegador, incluida la barra lateral (si se expande), ventana chrome y ventana redimensionando bordes / asas.

El estado de javascript es tal que uno no puede confiar en un significado específico para outerWidth en cada navegador en cada plataforma.

outerWidth es no está bien soportado en antiguos navegadores móviles, aunque goza de soporte en los principales navegadores de escritorio y la mayoría de los navegadores de teléfonos inteligentes más nuevos.

Como ausi señaló, matchMedia sería una gran opción ya que CSS está mejor estandarizado (matchMedia utiliza JS para leer el valores de vista detectados por CSS). Pero incluso con los estándares aceptados, los navegadores retrasados todavía existen que los ignoran (es decir,

En resumen, si solo está desarrollando para navegadores de escritorio y navegadores móviles más nuevos, outerWidth debería darle lo que está buscando, con algunas advertencias.

 1
Author: fzzylogic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-03-31 06:51:51

Aquí hay un truco menos complicado para lidiar con las consultas de medios. El soporte de navegador cruzado es un poco limitante, ya que no es compatible con IE móvil.

     if (window.matchMedia('(max-width: 694px)').matches)
    {
        //do desired changes
    }

Vea la documentación de Mozilla para más detalles.

 1
Author: user2128205,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-08 17:27:40

Solución que siempre funciona y se sincroniza con CSS media queries.

Añadir un div al cuerpo

<body>
    ...
    <div class='check-media'></div>
    ...
</body>

Agregue estilo y cámbielos ingresando en una consulta de medios específica

.check-media{
    display:none;
    width:0;
}
@media screen and (max-width: 768px) {
    .check-media{
         width:768px;
    }
    ...
}

Luego, en JS, verifique el estilo que está cambiando ingresando en media query

if($('.check-media').width() == 768){
    console.log('You are in (max-width: 768px)');
}else{
    console.log('You are out of (max-width: 768px)');
}

Por lo general, puede verificar cualquier estilo que se esté cambiando ingresando en una consulta de medios específica.

 0
Author: Arsen Pyuskyulyan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-08 17:41:48

La mejor solución cross-browser es utilizar Modernizr.mq

enlace: https://modernizr.com/docs/#mq

Modernizr.mq permite comprobar mediante programación si el estado actual de la ventana del navegador coincide con una consulta de medios.

var query = Modernizr.mq('(min-width: 900px)');
if (query) {
   // the browser window is larger than 900px
}

Nota El navegador no admite consultas de medios (por ejemplo, IE antiguo) mq siempre devolverá false.

 0
Author: Sanjib Debnath,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-18 07:24:29

Implementación deslizador slick y mostrar diferentes números de diapositivas en el bloque dependiendo de la resolución (jQuery)

   if(window.matchMedia('(max-width: 768px)').matches) {
      $('.view-id-hot_products .view-content').slick({
        infinite: true,
        slidesToShow: 3,
        slidesToScroll: 3,
        dots: true,
      });
    }

    if(window.matchMedia('(max-width: 1024px)').matches) {
      $('.view-id-hot_products .view-content').slick({
        infinite: true,
        slidesToShow: 4,
        slidesToScroll: 4,
        dots: true,
      });
    }
 -1
Author: Vitalii,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-08 09:44:34

Prueba esto

if (document.documentElement.clientWidth < 767) {
   // scripts
}

Para Más Referencia haga clic aquí

 -2
Author: Vaibs_Cool,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-10 09:32:07