首页 文章

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

提问于
浏览
163

我在一个项目上使用Twitter Bootstrap . 除了默认的bootstrap样式,我还添加了一些自己的样式

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

当视口的宽度小于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"));
    }
}

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

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

14 回答

  • 258

    使用

    window.innerWidth

    这解决了我的问题

  • 3

    是的,这是由滚动条引起的 . 正确答案来源: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' ] };
    }
    
  • -2

    这可能是一种更好的做法,不是JS-scope文档的宽度,而是由css @media查询做出的某种改变 . 使用此方法,您可以确保JQuery函数和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");
        ...
    });
    
  • 9

    最近我遇到了同样的问题 - 也是Bootstrap 3 .

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

    我提出的最佳解决方案 - 专为BS3量身定制 -
    check the width of a .container element.

    你可能知道 .container 元素是如何工作的,
    它是唯一能够为您提供BS css规则设置的当前宽度的元素 .

    所以它就像是

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

    这是前面提到的方法的替代方法,它依赖于通过CSS更改内容并通过Javascript读取它 . 此方法不需要 window.matchMedia 或Modernizr . 它也不需要额外的HTML元素 . 它通过使用HTML伪元素'store'断点信息来工作:

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

    我使用 body 作为示例,您可以使用任何HTML元素 . 您可以将任何所需的字符串或数字添加到伪元素的 content 中 . 不't have to be '移动'等等 .

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

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

    这样我们总能确定断点信息是正确的,因为它直接来自CSS,我们不必为通过Javascript获得正确的屏幕宽度而烦恼 .

  • 156

    始终有效的解决方法,并与CSS媒体查询同步 .

    在body中添加div

    <body>
        ...
        <div class='check-media'></div>
        ...
    </body>
    

    添加样式并通过输入特定的媒体查询来更改它们

    .check-media{
        display:none;
        width:0;
    }
    @media screen and (max-width: 768px) {
        .check-media{
             width:768px;
        }
        ...
    }
    

    然后在JS检查样式中,您将通过进入媒体查询进行更改

    if($('.check-media').width() == 768){
        console.log('You are in (max-width: 768px)');
    }else{
        console.log('You are out of (max-width: 768px)');
    }
    

    因此,通常您可以通过输入特定媒体查询来检查正在更改的任何样式 .

  • 1

    最好的跨浏览器解决方案是使用Modernizr.mq

    link: https://modernizr.com/docs/#mq

    Modernizr.mq允许您以编程方式检查当前浏览器窗口状态是否与媒体查询匹配 .

    var query = Modernizr.mq('(min-width: 900px)');
    if (query) {
       // the browser window is larger than 900px
    }
    

    Note 浏览器不支持媒体查询(例如旧IE)mq将始终返回false .

  • 2

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

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

    HTML:

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

    Javascript:

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

    CSS:

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

    实现光滑滑块并根据分辨率显示块中不同数量的幻灯片(jQuery)

    if(window.matchMedia('(max-width: 768px)').matches) {
          $('.view-id-hot_products .view-content').slick({
            infinite: true,
            slidesToShow: 3,
            slidesToScroll: 3,
            dots: true,
          });
        }
    
        if(window.matchMedia('(max-width: 1024px)').matches) {
          $('.view-id-hot_products .view-content').slick({
            infinite: true,
            slidesToShow: 4,
            slidesToScroll: 4,
            dots: true,
          });
        }
    
  • 3

    这可能是由于 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"));
    }
    

    你也可以得到 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' ] };
    }
    

    上面的代码 Source

  • -1

    这是处理媒体查询的一个较少参与的技巧 . 跨浏览器支持有点限制,因为它不支持移动IE .

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

    有关详细信息,请参阅Mozilla documentation .

  • 0

    Javascript提供了多种方法来检查视口宽度 . 如您所见,innerWidth不包括工具栏宽度,工具栏宽度因系统而异 . 还有 outerWidth 选项,其中包括工具栏宽度 . Mozilla Javascript API说:

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

    javascript的状态使得在每个平台上的每个浏览器中都不能依赖于outerWidth的特定含义 .

    outerWidthnot well supported on older mobile browsers,虽然它受到主要桌面浏览器和大多数较新的智能手机浏览器的支持 .

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

    summary 中,如果您仅针对桌面浏览器和较新的移动浏览器进行开发,则outerWidth应该使用some caveats为您提供所需内容 .

  • 4

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

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

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

    更新:

    如果您必须支持更多浏览器,则可以使用Modernizr's mq method,它支持所有了解CSS中媒体查询的浏览器 .

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

    试试这个

    if (document.documentElement.clientWidth < 767) {
       // scripts
    }
    

    如需更多参考,请单击 here

相关问题