检测像素比/密度的最佳做法是什么?

luk*_*ine 23 javascript mobile device-detection pixel-ratio

我目前正在我的网站上使用JavaScript进行移动设备检测,这样我就可以为移动或桌面用户提供不同的内容.

目前我使用window.devicePixelRatioscreen.width计算用户是否在移动设备上,如下:

var isMobileScreenWidth = ((screen.width / window.devicePixelRatio) < 768)
Run Code Online (Sandbox Code Playgroud)

768px 是我们定义移动或桌面的点,所以767及以下是移动,768及以上是桌面.

这很好用,但我最近遇到了Firefox的一个问题,当Firefox放大和缩小时会改变它window.devicePixelRatio,所以:

zoom = 30%, window.devicePixelRatio = 0.3
zoom = 100%, window.devicePixelRatio = 1.0
zoom = 300%, window.devicePixelRatio = 3.0
Run Code Online (Sandbox Code Playgroud)

现在这给我带来了一个问题,因为任何浏览器放大Firefox浏览器的用户都会获得该网站的移动版本.

我想知道是否有人知道一种不同的或更好的方法来获得与桌面浏览器分开的像素密度.

我也使用少量的用户代理检测但是因为跟上不断变化的移动用户代理列表是一项巨大的工作,所以我不可能同时依赖于屏幕分辨率和用户代理时间.

如果有人对此有任何想法,可以帮助那将是非常棒的.

更新:

我刚碰到过这个:

window.screen.availWidth / document.documentElement.clientWidth
Run Code Online (Sandbox Code Playgroud)

这篇文章建议使用这一快速数学:

window.devicePixelRatio在IE 10 Mobile中不起作用?

我测试了它并且它在Firefox中工作,并解决了我的问题,但遗憾的是现在导致Chrome出现问题,因此:

Chrome zoom = 100%,
window.devicePixelRatio = 1.0,
window.screen.availWidth / document.documentElement.clientWidth = 3.0
Run Code Online (Sandbox Code Playgroud)

我似乎无法找到适合一切的可靠解决方案.

Ama*_*lik 19

您应该通过<meta name="viewport" content="width=device-width"/>@-ms-viewport {width:device-width}功能利用制造商的提示.它基本上暴露了设备制造商认为最佳的默认缩放,给定屏幕的像素密度.执行此操作后,当您调用window.innerWidth它时,它将为您提供原始方程的用途,但不依赖于像素密度的测量.

避免依赖window.devicePixelRatio任何东西.它的意义和它返回的价值目前处于不稳定的状态,你现在所做的任何事情都很可能很快就会破裂.

注意:Meta视口仅适用于Android,iOS和Windows Phone 8. @-ms-viewport只能在IE10 Metro上正常工作,并且可能会干扰Windows Phone 8上正确的Meta视口行为.

  • 非常感谢你回复我,我已经完全失去了解决方案.所以如果你不认为使用`window.devicePixelRatio`是一个安全的选项,你会用什么呢?我已经看过很多检测移动设备的选项,遗憾的是我无法使用服务器端解决方案,所以JavaScript是我唯一的选择. (2认同)

And*_*kyi 8

有一个通用的解决方案来获取设备像素比

下一个代码window.devicePixelRatio用作起点,也有基于window.matchMedia()Web API的回退。

浏览器对这两个功能的支持几乎是完美的,所以这对于大多数用例来说应该是很好的。

这是一个检索此信息的函数,最初由 PatrickJS 编写并作为 GitHub Gist 发布

function getDevicePixelRatio() {
    var mediaQuery;
    var is_firefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1;
    if (window.devicePixelRatio !== undefined && !is_firefox) {
        return window.devicePixelRatio;
    } else if (window.matchMedia) {
        mediaQuery = "(-webkit-min-device-pixel-ratio: 1.5),\
          (min--moz-device-pixel-ratio: 1.5),\
          (-o-min-device-pixel-ratio: 3/2),\
          (min-resolution: 1.5dppx)";
        if (window.matchMedia(mediaQuery).matches) {
            return 1.5;
        }
        mediaQuery = "(-webkit-min-device-pixel-ratio: 2),\
          (min--moz-device-pixel-ratio: 2),\
          (-o-min-device-pixel-ratio: 2/1),\
          (min-resolution: 2dppx)";
        if (window.matchMedia(mediaQuery).matches) {
            return 2;
        }
        mediaQuery = "(-webkit-min-device-pixel-ratio: 0.75),\
          (min--moz-device-pixel-ratio: 0.75),\
          (-o-min-device-pixel-ratio: 3/4),\
          (min-resolution: 0.75dppx)";
        if (window.matchMedia(mediaQuery).matches) {
            return 0.7;
        }
    } else {
        return 1;
    }
}
Run Code Online (Sandbox Code Playgroud)

有用的链接MDN - window.devicePixelRatioMDN - Window.matchMedia()

可以使用: window.devicePixelRatio,Window.matchMedia()

  • 2019 年最好的方法是`return window.devicePixelRatio || 1;` (4认同)