如何让CSS mediaqueries与jQuery $(window).innerWidth()一起使用?

我正在尝试让jQuery处理菜单,而CSS在调整浏览器大小时会对窗口背景做些什么。

所以jQuery做了这样的事情:

if ( $(window).innerWidth() < mediaQueries['small']) { // (where 'small' would be 966) // Perform jQuery stuff on a menu ul } 

CSS有这样的东西:

 @media all and (max-width: 966px) { body { background: url(smallback.jpg) no-repeat 0 0; } } 

当使用Firefox时,有一个17像素(似乎是垂直滚动条宽度)的间隙,其中已经处理了jQuery的东西,但CSS却没有。

由于其他浏览器可能会为其滚动条使用不同的宽度,因此只需在CSS中添加17px就无法解决问题。 那么如何让jQuery考虑滚动条呢? $(window).innerWidth()似乎对我没那么做。

任何帮助将不胜感激。

在Firefox,Opera或IE中打开此页面以查找问题的隔离版本。 (Chrome和Safari不会遇到这个问题。因此:Webkit:+ 1,Gecko:-1,Trident:-1,Presto:-1。)

除了JackieChiles的解决方案:

运用

  var width = Math.max($(window).width(),window.innerWidth); 

在任何浏览器中都可以获得没有滚动条的宽度。

这个解决方案(IMHO)更好,因为JS不依赖于任何CSS。

感谢JackieChiles和Arjen提供此解决方案!

我在与媒体查询完全相同的时间触发JavaScript的解决方案(即使面对这里看到的设备或浏览器怪癖)是触发我的window.resize逻辑以响应媒体查询所做的更改。 这是一个例子:

CSS

  #my-div { width: 100px; } @media all and (max-width: 966px) { #my-div { width: 255px; } } 

JavaScript的

  var myDivWidth; $(document).ready(function() { myDivWidth = $('#myDiv').width(); $(window).resize(function () { if ($('#myDiv').width() != myDivWidth) { //If the media query has been triggered myDivWidth = $('#myDiv').width(); //Your resize logic here (the jQuery menu stuff in your case) } }); }); 

在此示例中,每当#myDiv更改大小(触发媒体查询时将发生),您的jQueryresize逻辑也将运行。

为简单起见,我使用了元素宽度,但您可以轻松使用您正在更改的任何属性,例如body背景。

这种方法的另一个优点是它使window.resize函数保持尽可能轻量级,这总是很好,因为每次窗口大小改变一个像素就会调用它(无论如何在大多数现代浏览器中)。

正如您所说,您遇到的错误在我看来是一个特定于浏览器的问题。 虽然直觉上似乎不正确,但Firefox(以及其他具有此问题的浏览器)实际上似乎与Webkit浏览器相比,更符合W3C对媒体查询的建议 。 建议指出视口宽度包括滚动条,JavaScript窗口宽度似乎不包括滚动条,因此不相容。

如果您正在使用Modernizr ,则可以包含媒体查询polyfill,这会将媒体查询检查简化为:

 if (Modernizr.mq('all and (max-width: 966px)')) { ... } 

哪个方便与CSS相同:

 @media all and (max-width: 966px) { ... } 

如果你不能使用Modernizr的polyfill,那么坚持检查Math.max(document.width, window.innerWidth)

window.matchMedia是一种在媒体选择器启动或关闭时可以触发事件的方法。 它是新的,因此得不到广泛支持,但似乎非常有用。

来自MDN的“使用来自代码的媒体查询”

 var viewport = jQuery(window).innerWidth(); if( viewport > 979 ) { // your code here }