CSS 媒体查询和 JavaScript 窗口宽度不匹配

IT技术 javascript jquery media-queries
2021-01-31 23:20:13

对于响应式模板,我的 CSS 中有一个媒体查询:

@media screen and (max-width: 960px) {
 body{
 /*  something */
 background:red;
 }
}

而且,我在调整大小以记录宽度时制作了一个 jQuery 函数:

$(window).resize(function() {
 console.log($(window).width());
 console.log($(document).width()); /* same result */
 /* something for my js navigation */
}

CSS检测和JS结果存在差异,我有这个元:

<meta content="user-scalable=no, initial-scale=1.0, maximum-scale=1.0, width=device-width" name="viewport"/> 

我想这是由于滚动条(15 像素)。我怎样才能做得更好?

6个回答

您对滚动条是正确的,这是因为 CSS 使用的是设备宽度,而 JS 使用的是文档宽度。

您需要做的是在您的 JS 代码中测量视口宽度,而不是使用 jQuery 宽度函数。

此代码来自http://andylangton.co.uk/articles/javascript/get-viewport-size-javascript/

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' ] };
}
坚硬的。比 $(document).width() 好得多;window.matchMedia() 可能更好,但它的 IE10+
2021-03-16 23:20:13
如果窗口有滚动条并且您的媒体查询正在检查最大宽度,这似乎不起作用,至少在 Chrome 中是这样。在您知道由特定媒体查询设置的元素上检查一些 css 似乎可以工作。
2021-03-24 23:20:13
@mhenry1384 你在说什么?
2021-04-01 23:20:13

我在http://www.w3schools.com/js/js_window.asp上找到了以下代码

var w=window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;

实际上,它的工作方式与@Michael Bird 的答案中的答案相同,但更易于阅读。

编辑:我正在寻找一种方法来提供与用于 css 媒体查询的宽度完全相同的宽度。但是建议的一个在带有滚动条的 Safari 上并不完美,抱歉。我最终在一个核心功能中使用了 Modernizr.js,而在其余代码中,我只检查显示类型是移动设备、平板电脑还是桌面设备。由于我对宽度不感兴趣,这对我来说很好用:

getDisplayType = function () {
  if (Modernizr.mq('(min-width: 768px)')){
    return 'desktop';
  }
  else if (Modernizr.mq('(min-width: 480px)')){
    return 'tablet'
  }
  return 'mobile';
};
如果document.documentElement不存在,此脚本将失败。不要相信 w3schools,请参阅w3fools.com
2021-03-14 23:20:13
好的,似乎没有浏览器没有document.documentElement. 不知道。
2021-03-23 23:20:13
@ausi:请你比“不要相信w3schools”更友善和详细一点吗?到目前为止我看不到问题。另请参阅document.documentElement 的任何跨浏览器问题
2021-03-31 23:20:13

window.innerWidth 正是你所需要的。

if (window.innerWidth < 768) 适用于 CSS 中的 768 断点

为什么它不是最佳答案?它非常简短,无需 jQuery 即可工作。伟大的!
2021-03-23 23:20:13
在 Safari 中,当媒体查询触发 768px 时,window.innerWidth 返回 783(不是 768)
2021-04-07 23:20:13

我的经验是媒体查询宽度跟踪 document.body.clientWidth。由于垂直滚动条来来往往,检查文档、窗口或视口().width 可能会导致我的 Javascript 运行延迟——在媒体查询规则更改后,取决于窗口的高度。

检查 document.body.clientWidth 允许我的脚本代码在媒体查询规则生效的同时一致地执行。

@media (min-width:873px) {
     //一些规则
}
...

if ( document.body.clientWidth >= 873) {
    // 一些代码
}

Andy Langton 代码让我明白了这一点——谢谢!

如果身体比屏幕宽,这将不起作用。我看到了一个不可见的 div 被定位固定并且它的宽度设置为 100% 的解决方案。使用它的 clientWidht 应该可以。
2021-03-20 23:20:13

嗨,我使用这个小技巧让 JS 和 CSS 在响应式页面上轻松协同工作:

测试元素在 CSS @media 大小条件下是否显示的可见性。使用 bootstrap CSS 我测试 hidden-xs 类元素的可见性

var msg = "a message for U";

/* At window load check initial size  */
if ( $('#test-xsmall').is(':hidden')  ) {
  /* This is a CSS Xsmall situation ! */
  msg = "@media CSS < 768px. JS width = " + $(window).width() + " red ! ";
  $('.redthing-on-xsmall').addClass('redthing').html(msg);

} else {
  /* > 768px according to CSS  */
  msg = "@media CSS > 767px. JS width = " + $(window).width() + " not red ! ";
  $('.redthing-on-xsmall').removeClass('redthing').html(msg);
}


/* And again when window resize  */

$(window).on('resize', function() {
  if ($('#test-xsmall').is(':hidden')) {
    msg = "@media CSS < 768px. JS width = " + $(window).width() + " red ! ";
    $('.redthing-on-xsmall').addClass('redthing').html(msg);
  } else {
    msg = "@media CSS > 767px. JS width = " + $(window).width() + " not red ! ";
    $('.redthing-on-xsmall').removeClass('redthing').html(msg);
  }
});
@media (min-width: 768px) {
  .hidden-xs {
    display: block !important;
  }
}
@media (max-width: 767px) {
  .hidden-xs {
    display: none !important;
  }
}
.redthing-on-xsmall {
  /* need a scrollbar to show window width diff between JS and css */
  min-height: 1500px;
}
.redthing {
  color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<!-- the CSS managed Element that is tested by JS --> 
<!-- class hidden-xs hides on xsmall screens (bootstrap) -->

<span id="test-xsmall" class="hidden-xs">THIS ELEMENT IS MANAGED BY CSS  HIDDEN on @media lower than 767px</span>


<!-- the responsive element managed by Jquery  -->
<div class="redthing-on-xsmall">THIS ELEMENT IS MANAGED BY JQUERY RED on @media max width 767px </div>