jQuery $(window).width() 与媒体查询不同

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19291873/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 23:36:13  来源:igfitidea点击:

$(window).width() not the same as media query

jquerycsstwitter-bootstrapmedia-queries

提问by Pattle

I am using Twitter Bootstrap on a project. As well as the default bootstrap styles I have also added some of my own

我在一个项目上使用 Twitter Bootstrap。除了默认的引导程序样式,我还添加了一些我自己的样式

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

I am also using jQuery to change the order of certain elements on the page when the width of the viewport is less that 767px.

当视口的宽度小于 767px 时,我还使用 jQuery 更改页面上某些元素的顺序。

$(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"));
    }
}

The problem I am having is that the width calculated by $(window).width()and the width calculated by the CSS doesn't seem to be the same. When $(window).width()returns 767 the css calculates it the viewport width as 751 so there seems to be a 16px different.

我遇到的问题是$(window).width()CSS 计算的宽度和 CSS 计算的宽度似乎不同。当$(window).width()返回 767 时,css 将视口宽度计算为 751,因此似乎有 16px 不同。

Does anyone know what is causing this and how I could solve the problem? People have suggested that the width of the scrollbar isn't being taken into considering and using $(window).innerWidth() < 751is the way to go. However ideally I want to find a solution that calculates the width of the scrollbar and that is consistent with my media query (e.g where both conditions are checking against the value 767). Because surely not all browsers will have a scrollbar width of 16px?

有谁知道是什么导致了这个问题以及我如何解决这个问题?人们建议不要考虑滚动条的宽度,而使用$(window).innerWidth() < 751是要走的路。然而,理想情况下,我想找到一个计算滚动条宽度并且与我的媒体查询一致的解决方案(例如,两个条件都检查值 767)。因为肯定不是所有浏览器的滚动条宽度都是 16px?

回答by ausi

If you don't have to support IE9 you can just use window.matchMedia()(MDN documentation).

如果您不必支持 IE9,则可以使用window.matchMedia()MDN 文档)。

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

window.matchMediais fully consistent with the CSS media queries and the browser support is quite good: http://caniuse.com/#feat=matchmedia

window.matchMedia与 CSS 媒体查询完全一致,浏览器支持相当好:http: //caniuse.com/#feat=matchmedia

UPDATE:

更新:

If you have to support more browsers you can use Modernizr's mq method, it supports all browsers that understand media queries in CSS.

如果您必须支持更多浏览器,您可以使用Modernizr 的 mq 方法,它支持所有理解 CSS 媒体查询的浏览器。

if (Modernizr.mq('(max-width: 767px)')) {
    //...
} else {
    //...
}

回答by NateS

Check a CSS rule that the media query changes. This is guaranteed to always work.

检查媒体查询更改的 CSS 规则。这保证始终有效。

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

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

HTML:

HTML:

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

Javascript:

Javascript:

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

CSS:

CSS:

#mobile-indicator {
    display: none;
}

@media (max-width: 767px) {
    #mobile-indicator {
        display: block;
    }
}

回答by Rohan Kumar

It may be due to scrollbar, use innerWidthinstead of widthlike

这可能是由于scrollbar,使用innerWidth而不是width喜欢

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"));
}

Also you can get the viewportlike

你也可以得到viewport

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' ] };
}

Above code Source

以上代码来源

回答by Rantiev

yes, that's due to scrollbar. Right answer source: enter link description here

是的,这是由于滚动条。正确答案来源:在此处输入链接描述

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' ] };
}

回答by gramgram

It's maybe a better practice not to JS-scope the document's width but some sort of change made by css @media query. With this method you can be sure the JQuery function and css change happens at the same time.

最好不要将文档的宽度设为 JS 范围,而是通过 css @media 查询进行某种更改。使用此方法,您可以确保 JQuery 函数和 css 更改同时发生。

css:

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");
    ...
});

回答by user3041539

I was facing the same problem recently - also with Bootstrap 3.

我最近遇到了同样的问题——Bootstrap 3 也是如此。

Neither $.width() nor $.innerWidth() will work for you.

$.width() 和 $.innerWidth() 都不适合你。

The best solution I came up with - and is specifically tailored to BS3 -
is to check the width of a .containerelement.

我想出的最佳解决方案 - 并且专门为 BS3 量身定制 -
检查.container元素的宽度。

As you probably know how the .containerelement works,
it's the only element that will give you the current width set by BS css rules.

您可能知道.container元素的工作原理,
它是唯一可以为您提供 BS css 规则设置的当前宽度的元素。

So it goes something like

所以它就像

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");

回答by user4451021

Use

window.innerWidth

window.innerWidth

This solved my problem

这解决了我的问题

回答by dschenk

Here is an alternative to the methods mentioned earlier that rely on changing something via CSS and reading it via Javascript. This method does not need window.matchMediaor Modernizr. It also needs no extra HTML element. It works by using a HTML pseudo-element to 'store' breakpoint information:

这是前面提到的依赖于通过 CSS 更改某些内容并通过 Javascript 读取它的方法的替代方法。此方法不需要window.matchMedia或 Modernizr。它还不需要额外的 HTML 元素。它通过使用 HTML 伪元素来“存储”断点信息:

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";
  }
}

I used bodyas an example, you can use any HTML element for this. You can add any string or number you want into the contentof the pseudo-element. Doesn't have to be 'mobile' and so on.

body举了一个例子,你可以为此使用任何 HTML 元素。您可以将您想要的任何字符串或数字添加到content伪元素的 中。不必是“移动的”等等。

Now we can read this information from Javascript in the following way:

现在我们可以通过以下方式从 Javascript 中读取这些信息:

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

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

This way we are always sure that the breakpoint information is correct, since it is coming directly from CSS and we don't have to hassle with getting the right screen-width via Javascript.

通过这种方式,我们始终可以确保断点信息是正确的,因为它直接来自 CSS,我们不必为通过 Javascript 获得正确的屏幕宽度而烦恼。

回答by fzzylogic

Javascript provides more than one method to check the viewport width. As you noticed, innerWidth doesn't include the toolbar width, and toolbar widths will differ across systems. There is also the outerWidthoption, which will include the toolbar width. The Mozilla Javascript APIstates:

Javascript 提供了不止一种方法来检查视口宽度。正如您所注意到的,innerWidth 不包括工具栏宽度,并且工具栏宽度会因系统而异。还有outerWidth选项,它将包括工具栏宽度。在Mozilla的JavaScript API第状态:

Window.outerWidth gets the width of the outside of the browser window. It represents the width of the whole browser window including sidebar (if expanded), window chrome and window resizing borders/handles.

Window.outerWidth 获取浏览器窗口外部的宽度。它代表整个浏览器窗口的宽度,包括侧边栏(如果展开)、窗口镶边和窗口大小调整边框/手柄。

The state of javascript is such that one cannot rely on a specific meaning for outerWidth in every browser on every platform.

javascript 的状态是这样的,以至于人们不能依赖于每个平台上每个浏览器中的 outerWidth 的特定含义。

outerWidthis not well supported on oldermobile browsers, though it enjoys support across major desktop browsers and most newer smart phone browsers.

outerWidth虽然它在主要桌面浏览器和大多数较新的智能手机浏览器中受到支持,但较旧的移动浏览器上没有得到很好的支持

As ausi pointed out, matchMediawould be a great choice as CSS is better standardised (matchMedia uses JS to read the viewport values detected by CSS). But even with accepted standards, retarded browsers still exist that ignore them (IE < 10 in this case, which makes matchMedia not very useful at least until XP dies).

正如ausi 指出的那样,matchMedia这将是一个不错的选择,因为CSS 更加标准化(matchMedia 使用JS 来读取CSS 检测到的视口值)。但即使采用了公认的标准,仍然存在忽略它们的延迟浏览器(在这种情况下,IE < 10,这使得 matchMedia 至少在 XP 死亡之前不是很有用)。

In summary, if you are only developing for desktop browsers and newer mobile browsers, outerWidth should give you what you are looking for, with some caveats.

总之,如果你只为桌面浏览器和新的移动浏览器开发,outerWidth应该给你你在找什么,有一些注意事项

回答by user2128205

Here's a less involved trick to deal with media queries. Cross browser support is a bit limiting as it doesn't support mobile IE.

这是处理媒体查询的一个不太复杂的技巧。跨浏览器支持有点限制,因为它不支持移动 IE。

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

See Mozilla documentationfor more details.

有关更多详细信息,请参阅Mozilla 文档