【问题标题】:$(window).width() not the same as media query$(window).width() 与媒体查询不同
【发布时间】:2013-10-17 23:36:00
【问题描述】:

我在一个项目中使用 Twitter 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() &lt; 751 是要走的路。但是理想情况下,我想找到一个计算滚动条宽度并且与我的媒体查询一致的解决方案(例如,两个条件都检查值 767)。因为肯定不是所有浏览器都有 16px 的滚动条宽度?

【问题讨论】:

标签: jquery css twitter-bootstrap media-queries


【解决方案1】:

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

你也可以得到viewportlike

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

【讨论】:

  • 谢谢。这会起作用,但无论如何我可以使用 jquery 来包含滚动条的宽度。我只是在想滚动条的宽度可能会在不同的浏览器上发生变化?
  • 是的,请使用innerWidth(),或者您可以像$('body').innerWidth(); 一样使用它,请参阅stackoverflow.com/questions/8339377/…
  • 你的意思是window.innerWidth,不在jQuery $(window)对象上,$(window).width()返回不正确
  • 如果在 OSX 系统首选项中启用了滚动条,window.innerWidth 与 Safari 8 中的 CSS 媒体查询不一致。
【解决方案2】:

试试这个

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

更多参考请点击here

【讨论】:

  • 谢谢,结果还是一样
【解决方案3】:

检查媒体查询更改的 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;
    }
}

【讨论】:

  • 这是一个比其他答案中提到的 JS hacks 更优雅的解决方案。
  • +1 这很聪明。我喜欢如果你想改变断点,你所要做的就是改变css而不是javascript。
  • 这个解决方案运行良好,我发现它比投票最多的答案中提出的 javascript hack 更优雅。
  • 如果你使用引导程序,你可以在没有 css 的情况下做到这一点,比如 &lt;div id="xs-indicator" class="xs-visible"&gt;
【解决方案4】:

是的,这是由于滚动条。正确答案来源: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' ] };
}

【讨论】:

    【解决方案5】:

    最好不要对文档的宽度进行 JS 限定,而是通过 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");
        ...
    });
    

    【讨论】:

      【解决方案6】:

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

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

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

      您可能知道.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");
      

      【讨论】:

        【解决方案7】:

        如果您不必支持 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 {
            //...
        }
        

        【讨论】:

        • 如果您有能力使用 Modernizr 库,这是最好的答案。
        • 这个解决方案更好:stackoverflow.com/a/19292035/1136132(第二个代码)。只有 JS。
        • @edwardm Modernizr.mq 只返回一个布尔值,因此您必须在onresize 事件处理程序中自己调用它。
        • @Bernig window.matchMedia 是推荐的方式,因为它不会触发reflow,这取决于您调用该函数的频率,这可能会导致性能问题。如果不想直接使用Modernizr,可以从src/mq.jssrc/injectElementWithStyles.js复制源码。
        • @KurtLagerbier 是的,这可行,但您也可以使用更简单的方法,像这样组合两个媒体查询:window.matchMedia('(min-width: 568px) and (max-width: 767px)').matches
        【解决方案8】:

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

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

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

        outerWidthnot well supported on older mobile browsers,尽管它在主要桌面浏览器和大多数较新的智能手机浏览器中都受到支持。

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

        总结中,如果您只是为桌面浏览器和较新的移动浏览器进行开发,outerWidth 应该为您提供所需的内容,some caveats

        【讨论】:

          【解决方案9】:

          使用

          window.innerWidth

          这解决了我的问题

          【讨论】:

            【解决方案10】:

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

            在正文中添加一个 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)');
            }
            

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

            【讨论】:

              【解决方案11】:

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

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

              更多详情请见Mozilla documentation

              【讨论】:

                【解决方案12】:

                这是前面提到的依赖于通过 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";
                  }
                }
                

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

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

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

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

                【讨论】:

                • 您不需要使用querySelector()getPropertyValue()。您也可以在正则表达式中查找单引号(因为它不一致)。这个:window.getComputedStyle(document.body, ':after').content.replace(/"|'/g, '')。而且,为了降低成本,您可以将其包裹在下划线/lodash ._debounce() 中,等待约 100 毫秒。最后,将属性附加到 使输出可用于其他事物,例如在 vars 之外寻找原始标志/数据的工具提示禁用子句。示例:gist.github.com/dhaupin/f01cd87873092f4fe2fb8d802f9514b1
                【解决方案13】:

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

                链接: https://modernizr.com/docs/#mq

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

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

                注意浏览器不支持媒体查询(如旧IE)mq会一直返回false。

                【讨论】:

                  【解决方案14】:

                  实现slick滑块并根据分辨率在块中显示不同数量的幻灯片(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,
                        });
                      }
                  

                  【讨论】:

                    【解决方案15】:
                    if(window.matchMedia('(max-width: 768px)').matches)
                        {
                            $(".article-item").text(function(i, text) {
                    
                                if (text.length >= 150) {
                                    text = text.substring(0, 250);
                                    var lastIndex = text.lastIndexOf(" ");     
                                    text = text.substring(0, lastIndex) + '...'; 
                                }
                    
                                $(this).text(text);
                    
                            });
                    
                        }
                    

                    【讨论】:

                      【解决方案16】:

                      试试这个

                      getData(){
                          if(window.innerWidth <= 768) {
                            alert('mobile view')
                            return;
                          }
                      
                         //else function will work
                      
                          let body= {
                            "key" : 'keyValue'
                          }
                          this.dataService.getData(body).subscribe(
                            (data: any) => {
                              this.myData = data
                            }
                          )
                      }
                      

                      【讨论】:

                        【解决方案17】:

                        我在做什么;

                        <body>
                        <script>
                        function getWidth(){
                        return Math.max(document.body.scrollWidth,
                        document.documentElement.scrollWidth,
                        document.body.offsetWidth,
                        document.documentElement.offsetWidth,
                        document.documentElement.clientWidth);
                        }
                        var aWidth=getWidth();
                        </script>
                        ...
                        

                        然后在任何地方调用 aWidth 变量。

                        您需要将 getWidth() 放在文档正文中以确保计算滚动条宽度,否则从 getWidth() 中减去浏览器的滚动条宽度。

                        【讨论】:

                          【解决方案18】:

                          如果您想每 1 秒检查一次设备中的屏幕宽度,您可以这样做

                           setInterval(function() {
                                  if (window.matchMedia('(max-width: 767px)').matches) {
                                      alert('here')
                                  } else {
                                      alert('i am ')
                                  }
                              }, 1000);
                          

                          【讨论】:

                          • 请不要这样做。这是一个非常糟糕的建议,因为MediaQueryListmatchMedia 返回的类型有一种注册侦听器的方法,可用于在评估结果更改时收到通知。
                          猜你喜欢
                          • 2013-12-12
                          • 1970-01-01
                          • 1970-01-01
                          • 2013-04-27
                          • 1970-01-01
                          • 2013-02-22
                          • 1970-01-01
                          • 2013-02-28
                          相关资源
                          最近更新 更多