【问题标题】:Get the device width in javascript在javascript中获取设备宽度
【发布时间】:2011-10-14 13:50:44
【问题描述】:

有没有办法使用 javascript 获取用户设备宽度,而不是视口宽度?

CSS 媒体查询提供了这一点,我可以说

@media screen and (max-width:640px) {
    /* ... */
}

@media screen and (max-device-width:960px) {
    /* ... */
}

如果我将智能手机定位为横向,这很有用。例如,在 iOS 上,max-width:640px 的声明将针对横向和纵向模式,即使在 iPhone 4 上也是如此。据我所知,Android 并非如此,因此在此实例中使用 device-width 成功地针对两个方向,不针对桌面设备。

但是,如果我基于设备宽度调用 javascript 绑定,我似乎仅限于测试视口宽度,这意味着需要额外的测试,如下所示,

if ($(window).width() <= 960 && $(window).height <= 640) { /* ... */ }

考虑到设备宽度可用于 css 的提示,这对我来说似乎并不优雅。

【问题讨论】:

标签: javascript css media-queries


【解决方案1】:

您可以通过screen.width 属性获取设备屏幕宽度。 有时,在处理窗口大小通常小于设备屏幕大小的桌面浏览器时,使用window.innerWidth(通常在移动设备上找不到)而不是屏幕宽度也很有用。

通常,在处理移动设备和桌面浏览器时,我使用以下内容:

 var width = (window.innerWidth > 0) ? window.innerWidth : screen.width;

【讨论】:

  • 我注意到这在 Android 2.2 本机浏览器上无法正常工作。如果我不是 1:1 的比例,它可以报告更宽的宽度(与页面一样宽),这有点令人沮丧。
  • 这在 Android 上的 Chrome Beta 上返回 980,在 HTC Vive 上的 Android 浏览器上返回 1024。
  • @Alex 这些是浏览器的默认视口宽度。如果您使用带有width=device-width 的视口元标记,您应该得到实际值。
  • window.innerWidth 在 Iphone (Chrome/Safari) 上返回 980。那个怎么样? 没有区别。
  • 这怎么会有这么多赞? var width = (window.innerWidth &gt; 0) ? window.innerWidth : screen.width; 在 iphone 6 和 6 Plus 上返回 667。此解决方案无法正常工作。
【解决方案2】:

Bryan Rieger 的有用答案的一个问题是,在高密度显示器上,Apple 设备报告 screen.width 的下降,而 Android 设备报告它的物理像素。 (见http://www.quirksmode.org/blog/archives/2012/07/more_about_devi.html。)我建议在支持matchMedia的浏览器上使用if (window.matchMedia('(max-device-width: 960px)').matches) {}

【讨论】:

  • 这似乎是一个更好的解决方案,实际上使用了 CSS 媒体查询。我想知道跨移动平台的浏览器支持是什么?
  • 这是正确的用法吗? if (window.matchMedia('(max-device-width: 960px)').matches) { var winW = (window.innerWidth &gt; 0) ? window.innerWidth : screen.width; } else { var winW = screen.width; }
  • 我不确定如果没有将缩放比例设置为 1:1 作为基础,这是否可行...var isMobile = window.matchMedia &amp;&amp; window.matchMedia('(max-device-width: 960px)').matches || screen.width &lt;= 960;
  • 对于不支持matchMedia()的浏览器,有一个polyfill:github.com/paulirish/matchMedia.js
  • 根据caniuse.com,几乎所有浏览器,包括移动端,都支持window.matchMedia()
【解决方案3】:

我刚刚有这个想法,所以可能是短视的,但它似乎运作良好,并且可能是您的 CSS 和 JS 之间最一致的。

在您的 CSS 中,您根据 @media 屏幕值设置 html 的最大宽度值:

@media screen and (max-width: 480px) and (orientation: portrait){

    html { 
        max-width: 480px;
    }

    ... more styles for max-width 480px screens go here

}

然后,使用 JS(可能通过 JQuery 之类的框架),您只需检查 html 标签的最大宽度值:

maxwidth = $('html').css('max-width');

现在您可以使用此值进行有条件的更改:

If (maxwidth == '480px') { do something }

如果将 max-width 值放在 html 标签上看起来很吓人,那么也许您可以放置​​一个不同的标签,一个仅用于此目的的标签。出于我的目的,html 标记可以正常工作并且不会影响我的标记。


在您使用 Sass 等时很有用:要返回更抽象的值,例如断点名称,而不是 px 值,您可以执行以下操作:

  1. 创建一个将存储断点名称的元素,例如&lt;div id="breakpoint-indicator" /&gt;
  2. 使用 css 媒体查询更改此元素的内容属性,例如。 G。 “large”或“mobile”等(与上述基本媒体查询方法相同,但设置 css 'content' 属性而不是 'max-width')。
  3. 使用 js 或 jquery 获取 css 内容属性值(jquery 例如$('#breakpoint-indicator').css('content');),根据媒体查询设置的内容属性返回“大”或“移动”等。
  4. 根据当前值操作。

现在您可以像在 sass 中一样对相同的断点名称进行操作,例如sass:@include respond-to(xs),和 js if ($breakpoint = "xs) {}

我特别喜欢这一点的是,我可以在 css 中和一个地方(可能是变量 scss 文档)定义我的断点名称,并且我的 js 可以独立地对它们进行操作。

【讨论】:

    【解决方案4】:

    你应该使用

    document.documentElement.clientWidth
    

    它被认为是跨浏览器的兼容性,和jQuery(window).width()的方法一样;用途。

    详情请看:https://ryanve.com/lab/dimensions/

    【讨论】:

      【解决方案5】:

      检查一下

      const mq = window.matchMedia( "(min-width: 500px)" );
      
      if (mq.matches) {
        // window width is at least 500px
      } else {
        // window width is less than 500px
      }
      

      https://developer.mozilla.org/en-US/docs/Web/API/Window/matchMedia

      【讨论】:

        【解决方案6】:

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

        这应该可以处理大多数情况。

        【讨论】:

        • Math.max(window.innerWidth);将为您提供宽度,包括 FireFox、Edge 和 Chrome 中的滚动条。 document.documentElement.clientWidth;将给出这些浏览器中任何滚动条内的宽度。在 IE 11 中,两者都将显示包括滚动条在内的宽度..
        【解决方案7】:

        您可以轻松使用

        document.documentElement.clientWidth

        更新

        例如:

        let el = document.getElementById('result');
        el.innerText = document.documentElement.clientWidth;
        window.addEventListener('resize', function(event) {
            // do what you want
            el.innerText = document.documentElement.clientWidth;
        }, true);
        <!DOCTYPE html>
          <html>
             <body>
              <div id="result"></div>
             </body>
          </html>

        【讨论】:

        • 一般来说,如果答案包含对代码的用途的解释,以及为什么在不介绍其他人的情况下解决问题的原因,答案会更有帮助。
        • @TimDiekmann 你是对的。只是添加了一个简单的例子来澄清答案。
        【解决方案8】:

        我认为使用window.devicePixelRatiowindow.matchMedia 解决方案更优雅:

        if (window.innerWidth*window.devicePixelRatio <= 960 
            && window.innerHeight*window.devicePixelRatio <= 640) { 
            ... 
        }
        

        【讨论】:

          【解决方案9】:

          Lumia 手机的 screen.width 错误(至少在模拟器上)。 那么Math.min(window.innerWidth || Infinity, screen.width) 可能适用于所有设备?

          或者更疯狂的:

          for (var i = 100; !window.matchMedia('(max-device-width: ' + i + 'px)').matches; i++) {}
          var deviceWidth = i;
          

          【讨论】:

            【解决方案10】:

            基于 Bootstrap 设置其Responsive breakpoints 的方法,以下函数根据屏幕宽度返回 xs、sm、md、lg 或 xl:

            console.log(breakpoint());
            
            function breakpoint() {
                let breakpoints = {
                    '(min-width: 1200px)': 'xl',
                    '(min-width: 992px) and (max-width: 1199.98px)': 'lg',
                    '(min-width: 768px) and (max-width: 991.98px)': 'md',
                    '(min-width: 576px) and (max-width: 767.98px)': 'sm',
                    '(max-width: 575.98px)': 'xs',
                }
            
                for (let media in breakpoints) {
                    if (window.matchMedia(media).matches) {
                        return breakpoints[media];
                    }
                }
            
                return null;
            }

            【讨论】:

              【解决方案11】:

              你可以使用 document.documentElement.clientWidth 来获取客户端的设备宽度,并通过设置 setInterval 来跟踪设备宽度

              就像

              setInterval(function(){
                      width = document.documentElement.clientWidth;
                      console.log(width);
                  }, 1000);
              

              【讨论】:

              • 只需使用 onresize。例如 document.getElementsByTagName("BODY")[0].onresize = function()
              【解决方案12】:

              仅供参考,有一个名为 breakpoints 的库,它检测 CSS 中设置的最大宽度,并允许您在 JS if-else 条件下使用 、>= 和 = = 标志。我发现它非常有用。有效负载大小小于 3 KB。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2016-06-28
                • 1970-01-01
                • 2014-07-27
                • 1970-01-01
                • 2012-04-27
                • 2016-12-08
                • 1970-01-01
                • 2013-05-04
                相关资源
                最近更新 更多