如何让 CSS 媒体查询与 jQuery $(window).innerWidth() 一起使用?

Posted

技术标签:

【中文标题】如何让 CSS 媒体查询与 jQuery $(window).innerWidth() 一起使用?【英文标题】:How do I get CSS mediaqueries to work with jQuery $(window).innerWidth()? 【发布时间】:2012-01-18 08:14:54 【问题描述】:

我试图让 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 中打开 this page 以查看问题的独立版本。 (Chrome 和 Safari 没有遇到这个问题。到目前为止:Webkit:+1,Gecko:-1,Trident:-1,Presto:-1。)

【问题讨论】:

如果你使用 width() 会发生什么? @Ben 同样的事情,没关系。看起来 javascript 忘记了滚动条? 你能在某处设置一个基本示例供人们测试吗? 【参考方案1】:
var viewport = jQuery(window).innerWidth();

if( viewport > 979 )

  // your code here

【讨论】:

我很抱歉,但这甚至不是问题的答案。我认为你努力帮助其他人解决他们的问题是件好事,但如果你不了解他们的问题是什么,你就没有帮助。【参考方案2】:

如果您碰巧在使用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)

【讨论】:

【参考方案3】:

除了JackieChiles的解决方案:

使用

var width = Math.max( $(window).width(), window.innerWidth);
总是会在任何浏览器中为您提供不带滚动条的宽度。

这个解决方案(恕我直言)更好,因为 JS 不依赖任何 CSS。

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

【讨论】:

谢谢,这个解决方案对我有用。 jQuery 文档says 表示 .innerWidth() 不适用于窗口和文档对象;对于这些,请改用 .width() 。我已相应地编辑了您的答案。 我的问题在 webkit 浏览器中显示不佳。我不得不用这种方式来修复:isWebKit ? $(window).width() : Math.max($(window).width(), window.innerWidth);【参考方案4】:

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

"Using media queries from code" from MDN

【讨论】:

【参考方案5】:

我在与媒体查询完全相同的时间触发 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 改变大小(触发媒体查询时会发生)时,您的 jQuery 调整大小逻辑也将运行。

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

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

正如您所说,您遇到的错误在我看来是特定于浏览器的问题。虽然直观上看起来不正确,但 Firefox(和其他有问题的浏览器)实际上似乎比 Webkit 浏览器更接近于匹配 W3C recommendation for media queries。该建议指出视口宽度包括滚动条,而 JavaScript 窗口宽度似乎不包括滚动条,因此存在差异。

【讨论】:

非常感谢!虽然这是一种解决方法,但它确实是有用的建议,因为现在用户不会有任何不同。 @Simon:很高兴我能帮上忙。虽然媒体查询和 JavaScript 对宽度的定义并不总是一致,但确实令人沮丧。 @Simon 您应该将 Jackie 的答案标记为正确(在旁边打勾) @Simon:与 jQuery $(window).innerWidth() 相比,仅使用 window.innerWidth 即可为您提供包括滚动条在内的完整宽度。虽然window.innerWidth 可能会解决您在 Firefox 中的问题,但它会在 WebKit 浏览器中出现。 @JackieChiles 啊,太好了!忘记了 JS != JQ。 :-) 虽然我总是讨厌“if (IE) then ... if (FF) then ... if (Chrome) then ...”代码,但我想我们需要一段时间才能摆脱那个(如果有的话)。

以上是关于如何让 CSS 媒体查询与 jQuery $(window).innerWidth() 一起使用?的主要内容,如果未能解决你的问题,请参考以下文章

如何让 Wordpress 在 CSS 中读取我的媒体查询?

jQuery 和 CSS 媒体查询不同步

如何让桌面浏览器忽略 iPhone css3 媒体查询

使用 javascript 或 jQuery 生成 CSS 媒体查询

CSS媒体查询和选择器[重复]

如何将此媒体查询转换为 jquery?