jquery - div - ¿Por qué el window.width es más pequeño que el ancho de la ventana gráfica establecido en las consultas de medios?
set width jquery (7)
Estoy bastante desconcertado y todavía no estoy seguro de cómo explicar esto con las palabras adecuadas. Hasta ahora he usado y configurado mis consultas de medios con Breakpoint. Una variable de punto de interrupción usada se ve como por ejemplo:
$menustatictofixed: min-width 900px;
$ breakpoint-to-ems se establece en true. He trazado la página con todas sus variables de punto de interrupción basadas en los valores de píxeles del siguiente fragmento de jQuery:
$(''body'').append(''<div style="position: fixed; bottom: 0; right: 0; display: inline-block; font-weight: bold; padding: 5px 7px; border-radius: 5px 0 0 0; background: green; color: white; z-index: 9999;">Viewport width <span id="width"></span> px</div>'');
var viewportWidth = $(window).width()
$(''#width'').text(viewportWidth);
$(window).resize(function() {
var viewportWidth = $(window).width();
$(''#width'').text(viewportWidth);
});
Todo parecía correcto y limpio. Pero durante los últimos uno o dos días tuve problemas para configurar los últimos puntos de interrupción para un patrón y hacer que las cosas se comporten de manera predecible. De alguna manera, las cosas que parecían sumarse limpias y finas en primer lugar, que lógicamente ahora dudo mucho, son de hecho impropias y de alguna manera un desastre. Porque si miras la siguiente screenshot alguna manera, el ancho de la ventana (en Chrome) difiere del ancho del fragmento de jQuery que utiliza window.width. Tampoco hay una diferencia si reemplazaría window.width por window.innerWidth para descartar las barras de desplazamiento eventualmente. La única forma de recibir resultados adecuados es agregar 15 píxeles a la ecuación:
var viewportWidth = $(window).width() + 15;
¿Es el único problema en toda la ecuación que window.width es la elección incorrecta de la función y sería mejor ir con, por ejemplo, document.documentElement.clientWidth o algo más o ...? ¿Y en qué consisten los 15 píxeles por los que se solucionó el problema anterior de forma un tanto pirateada? Saludos cordiales Ralf
Es debido a la scrollbar''s
La solución más correcta que encontré es usar consultas de medios para pasar el tamaño real de la ventana a Javascript. Tienes que seguir estos pasos:
- Agrega un elemento oculto a tu página,
- Usar consultas de medios para alterar la propiedad de
max-width
de ese elemento, - Lee la propiedad de
max-width
de ese elemento a través de Javascript.
Por ejemplo, agregue el siguiente elemento a su página:
<div id="currentMedia"></div>
Luego escribe las siguientes reglas CSS:
#currentMedia {
display: none;
}
@media (max-width: 720px) {
// Make arrows in the carousel disappear...
#currentMedia {
max-width: 720px;
}
}
Luego, desde el lado de Javascript, puedes escribir:
if (parseInt(jQuery("#currentMedia").css("max-width"), 10) <= 720) {
// Code HERE..
}
Y será preciso independientemente del tamaño de la barra de desplazamiento, ya que el valor proviene de la misma consulta de medios que desencadena la desaparición del carrusel.
Probé esta solución en todos los principales navegadores recientes y da resultados correctos.
Encontrará el gran resumen de qué propiedades son compatibles con los navegadores en esta página en quirksmode.org .
Probablemente, lo mejor que puede hacer es tomar un elemento de la página (usando document.body donde se admite, o document.getElementById o lo que sea), recorrer su cadena offsetParent para encontrar el elemento superior, luego examinar el elemento ClientWidth y clientHeight.
Documentación innerWidth
.innerWidth()
método .innerWidth()
no es aplicable a objetos de window
y document
; para estos, use .width()
lugar.
Esto es lo que funcionó para mí: las consultas de medios CSS y el ancho de la ventana de JavaScript no coinciden .
En lugar de usar $(window).width();
que incluye barras de desplazamiento obtienen el ancho interior de esta manera:
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'' ] };
}
var vpWidth = viewport().width; // This should match your media query
La respuesta es barras de desplazamiento, y la solución es difícil.
Las consultas de los medios son interesantes. No se comportan exactamente igual en todos los navegadores, lo que significa que usarlos a veces no puede ser tan fácil. En -webkit / -blink en OS X e IE10 en Win8, por ejemplo, las barras de desplazamiento se superponen en la página. Sin embargo, en -moz, las barras de desplazamiento no se superponen en la página. La mejor manera de obtener el "área visible" de la página es la siguiente línea de JavaScript de vainilla (suponiendo que tenga un documento HTML válido):
document.body.parentNode.clientWidth
Lo que esto hará es encontrar el elemento del body
, encontrar su padre (que en un documento válido será el elemento html
), y luego encontrar su ancho después del renderizado. Esto te dará el ancho que estás interesado en ver. También es un ancho inútil para tener .
¿Por qué, se puede preguntar, es inútil el ancho real del cliente? No es porque varía de un navegador a otro, porque lo hace. ¡Es porque eso no es lo que realmente están probando las consultas de medios de width
! La prueba de width
las consultas de medios es window.innerWidth
, que es lo que en esencia estás usando ahora.
Entonces, ¿cuál es la solución a este problema? Bueno, diría que la solución es utilizar consultas de contenido basadas en contenido en lugar de consultas de soporte basadas en dispositivo y estar bien con cierto margen de maniobra en sus consultas (especialmente si ese margen de maniobra es de aproximadamente 15px
). Si aún no lo has hecho, lee los artículos Vexing Viewports y A Pixel Identity Crisis para tener una idea de por qué un posible brillo de 15px
en tus definiciones de MQ no es lo peor del mundo (probablemente hay peces más grandes para freír) .
Entonces, en conclusión, continúe usando $breakpoint-to-ems: true
y elija sus consultas de medios según el momento en que el contenido window.innerWidth
a window.innerWidth
ya que es la única forma window.innerWidth
de manejar los problemas de window.innerWidth
navegadores. Desde un breve vistazo a varios problemas, parece que la mayoría de los navegadores y sistemas operativos se están moviendo a una barra de desplazamiento superpuesta (a partir de Firefox 24, todos los navegadores OS X tendrán uno, la interfaz de usuario Unity de Ubuntu los presentó ), por lo que en un esfuerzo por ser amigable para el futuro , Sugiero que no se preocupe por el desplazamiento de la barra de desplazamiento y esté bien con los sitios que se ven ligeramente diferentes en el navegador. Recuerda, como Ethan Marcotte puso tan elocuentemente:
La web es un medio inherentemente inestable.
Use las clases en el cuerpo para definir si está en un dispositivo móvil, tableta o escritorio en lugar de utilizar píxeles.
Para mí no funcionó document.body.clientWidth
o innerWidth
. Mi funcionalidad falla entre 1023-1040px incluso si mi código js debe hacer esta declaración:
if($(window).width()<1024)
La solución fue poner en el cuerpo una nueva clase por menos de 1024 y denominarla "resolución pequeña" y usarla en mi código en lugar de la verificación de píxeles:
if($(body).hasClass(''small-res''))
Te lo recomiendo a ti también.
function getWindowWidth() {
var windowWidth = 0;
if (typeof(window.innerWidth) == ''number'') {
windowWidth = window.innerWidth;
}
else {
if (document.documentElement && document.documentElement.clientWidth) {
windowWidth = document.documentElement.clientWidth;
}
else {
if (document.body && document.body.clientWidth) {
windowWidth = document.body.clientWidth;
}
}
}
return windowWidth;
}
La respuesta de @Snugug da una muy buena explicación de por qué sucede esto, y @TusharGupta también tiene una buena solución que hace referencia al ancho detectado de mediaquery a javascript. La solución que se encuentra debajo va al revés utilizando el ancho detectado por javascript para desencadenar cambios en el diseño.
En caso de que necesite sincronizar mediaqueries con la detección de ancho de píxel de javascript, una forma de abordar el problema es desencadenar cambios en el diseño css según las clases que agregue con javascript.
Entonces, en lugar de escribir mediaqueries, escriba esas declaraciones anidadas en una clase, diga:
html.myMobileBP { ... }
Y en su javascript / jQuery, agregue esta clase como:
if ($(window).width() < myMobileBPPixelSize) {
$("html").addClass("myMobileBP");
}
Para llevar esto aún más lejos, es posible que desee considerar la falta de soporte de javascript. Defina mediaqueries que además están envueltas en una clase html.no-js
, luego, con javascript, elimine la clase .no-js
y aplique la solución anterior de agregar puntos de interrupción a través de clases javascript.
Similar a la respuesta de @ Snugugs pero funcionó mejor para mi caso de uso:
CSS (Tenga en cuenta que estoy usando MENOS, por lo que @tabletMin y @desktopMin se traducen en variables de punto de interrupción que he establecido en otros lugares:
#cssWidth {
display:none;
content:''mobile'';
}
/* Responsive styles (Tablet) */
@media (min-width: @tabletMin) {
#cssWidth {
content:''tablet'';
}
/* Other tablet CSS... */
}
/* Responsive styles (Desktop) */
@media (min-width: @desktopMin) {
#cssWidth {
content:''desktop'';
}
/* Other Desktop CSS... */
}
Y luego en JS:
getView = function() {
// If #cssWidth element does not exist, create it and prepend it do body
if ($(''#cssWidth'').length === 0) {
$(''body'').prepend($(document.createElement(''div'')).attr(''id'', ''cssWidth''));
}
// Return the value of the elements ''content'' property
return $(''#cssWidth'').css(''content'');
};
La función getView () devolverá la cadena ''móvil'', ''tableta'' o ''escritorio'' dependiendo del ancho que vean las consultas de los medios .
Esto podría extenderse para que se ajuste a más anchos de ventana gráfica, simplemente agregue más reglas en el CSS con otros valores.