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

时间:2013-05-14 11:11:28

标签: javascript mobile device-detection pixel-ratio

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

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

var isMobileScreenWidth = ((screen.width / window.devicePixelRatio) < 768)

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

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

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

我也会使用少量的用户代理检测,但由于跟上不断变化的移动用户代理列表是一项巨大的工作,因此我无法依赖屏幕分辨率和用户代理在同一时间。

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

更新:

我刚刚遇到过这个问题:

window.screen.availWidth / document.documentElement.clientWidth

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

window.devicePixelRatio does not work in IE 10 Mobile?

我已经测试了它并且它在Firefox中运行,并解决了我的问题,但不幸的是现在导致Chrome出现问题,所以:

Chrome zoom = 100%,
window.devicePixelRatio = 1.0,
window.screen.availWidth / document.documentElement.clientWidth = 3.0

我似乎无法找到适用于所有事情的可靠解决方案。

2 个答案:

答案 0 :(得分:17)

您应该通过<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视口行为。

答案 1 :(得分:1)

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

下一个代码以window.devicePixelRatio作为起点。但是还具有基于window.matchMedia() Web API的后备功能。

浏览器对这两个功能的支持几乎是完美的,因此这在大多数用例中都应该很好用。

这里是一个检索此信息的函数,originally written by PatrickJS and published as a 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;
    }
}

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

我可以使用window.devicePixelRatioWindow.matchMedia()