【问题标题】:What is the best way to detect retina support on a device using JavaScript?使用 JavaScript 在设备上检测视网膜支持的最佳方法是什么?
【发布时间】:2013-10-30 17:22:33
【问题描述】:

我现在正在使用这个功能:

function is_retina_device() {
    return window.devicePixelRatio > 1;
}

但它的简单让我害怕。有没有更彻底的检查?

【问题讨论】:

  • Retina 特别还是一般只支持高清? IIRC Retina 的像素比为2,但任何大于1 的都可以视为高清。
  • @AndréDion 所以我在 js 中这样做的原因是确定要提供哪个图像(常规或 2 倍大小)。所以我相信我只需要视网膜而不是高清。因为如果此函数返回 true,我会提供 2 倍大小的图像。
  • 如果你想要它用于图像,你可以使用这个retinajs.com
  • @TK123 我认为您所拥有的条件可以安全地执行您所描述的操作。即使设备的像素比不完全是2,但仍大于1,您仍然希望提供高清资源。您将提供更高分辨率的图像并将其缩小 - 无论设备的确切像素比如何,它都是相同的技术。
  • @AndréDion 现在会是 any >1 吗?为什么不超过 1.4?

标签: javascript jquery retina-display


【解决方案1】:

根据我最近阅读的所有内容,浏览器似乎正在朝着resolution 媒体查询表达式发展。这不是当前接受的答案中使用的device-pixel-ratiodevice-pixel-ratio 之所以只能用作备用,是因为它不是标准的媒体查询。

根据 w3.org:

曾几何时,Webkit 决定需要对屏幕分辨率进行媒体查询。但他们没有使用已经标准化的分辨率媒体查询,而是发明了-webkit-device-pixel-ratio。

View Full Article

Resolution Media Query Documentation

由于resolution 是标准化的,因此未来让我们首先在检测中使用它以进行未来的校对。另外,因为我不确定您是只想检测高 dppx 设备还是 only retina(仅限 Apple)设备,所以我已经添加了每一个设备。最后,请注意,Apple 检测只是用户代理嗅探,因此不能依赖。注意:对于isRetina 函数,我使用的 dppx 为 2 而不是 1.3,因为所有视网膜苹果设备都有 2dppx。

注意看来MS Edge has some issues with non integer values

function isHighDensity(){
    return ((window.matchMedia && (window.matchMedia('only screen and (min-resolution: 124dpi), only screen and (min-resolution: 1.3dppx), only screen and (min-resolution: 48.8dpcm)').matches || window.matchMedia('only screen and (-webkit-min-device-pixel-ratio: 1.3), only screen and (-o-min-device-pixel-ratio: 2.6/2), only screen and (min--moz-device-pixel-ratio: 1.3), only screen and (min-device-pixel-ratio: 1.3)').matches)) || (window.devicePixelRatio && window.devicePixelRatio > 1.3));
}


function isRetina(){
    return ((window.matchMedia && (window.matchMedia('only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx), only screen and (min-resolution: 75.6dpcm)').matches || window.matchMedia('only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (-o-min-device-pixel-ratio: 2/1), only screen and (min--moz-device-pixel-ratio: 2), only screen and (min-device-pixel-ratio: 2)').matches)) || (window.devicePixelRatio && window.devicePixelRatio >= 2)) && /(iPad|iPhone|iPod)/g.test(navigator.userAgent);
}

【讨论】:

  • 今天在我的配备 Retina 的 MacBook 上检查了 isRetina() 函数 - 它不起作用。
  • 同时使用 CSS 'or' (,) 和 JS 'or' (||) 的原因是什么?
  • @BinaryFunt 用于 CSS ,s 我们正在检查 min-resolution 的不同单位值(dpidppxdpcm),因为不同的浏览器支持不同的单位。 javascript ||s 是这样我们可以检查min-resolutionmin-device-pixel-ratio (再次因为不同的浏览器支持不同的媒体查询)。另外,有些浏览器不支持window.matchMedia,所以其他的|| 也要检查window.devicePixelRatio
  • @JomarSevillejo 在撰写本文时,Apple 仅有的视网膜显示器是 iPad、iPhone 和 iPod。这一行的唯一目的是检查浏览器的用户代理,无论如何都不应该信任它。这更像是一个例子。我建议使用isHighDensity 函数并将分辨率媒体查询更改为您的需要,而不是使用isRetina 函数。
  • @Novitchi 很有趣,according to the spec 值是一个正的 ,后面紧跟一个单位标识符”(强调我的),所以它看起来像 MS不符合规范。我会在答案中添加注释。
【解决方案2】:

如果你想要它用于图像,你可以使用retinajs 或者这个代码是检测它的常见响应:

function isRetinaDisplay() {
        if (window.matchMedia) {
            var mq = window.matchMedia("only screen and (min--moz-device-pixel-ratio: 1.3), only screen and (-o-min-device-pixel-ratio: 2.6/2), only screen and (-webkit-min-device-pixel-ratio: 1.3), only screen  and (min-device-pixel-ratio: 1.3), only screen and (min-resolution: 1.3dppx)");
            return (mq && mq.matches || (window.devicePixelRatio > 1)); 
        }
    }

【讨论】:

  • 非常感谢,为了安全起见,我将之前的支票添加到了这张mq && mq.matches || window.devicePixelRatio > 1
  • -moz-min-device-pixel-ratio 不正确。应该是min--moz-device-pixel-ratio。请在此处阅读注释:MDN@TK123
  • @Adam Merrifield 谢谢,您的评论来得正是时候。一位在 linux 机器上使用 firefox 的同事发现,即使他不在视网膜设备上,该功能也会返回 true。更新到 min--moz-device-pixel-ratio 解决了这个问题。我应该注意到,尽管样式表中的视网膜 css 没有在该机器上执行,但这整个函数(即使在修复之后)在 nexus 平板电脑上返回 true,这让我相信它在某些设备上错误地返回 true。也许还有更多,我只检查了一些。
  • @TK123 该功能工作正常。它测量输出设备的像素密度。 Retina 只是苹果在其设备上营销更高像素密度的方式。如果您想知道设备是否是 Apple Retina 设备,那么您可能还想匹配用户代理或使用特征检测来判断它是否是 idevice。话虽如此,nexus 7(2012 型号)具有 1.3dppx,而nexus 7(2013 型号)具有 2dppx。所以这是正确的。请查看this article 以查看具有 > 1dppx 的设备的简短列表
  • 如果您想要近似等效但仅在 CSS 中,请参阅gist.github.com/marcedwards/3446599 另请注意,如果您在图像标签本身中指定更高的等效分辨率,您甚至可能不需要retinajs,请参阅stackoverflow.com/a/43823483/32453跨度>
【解决方案3】:

实际上,如果您只关心现代浏览器,那么您在问题中使用的代码是完全正确的。 (见:http://caniuse.com/#feat=devicepixelratio

所有现代浏览器都实现了它,而旧浏览器只会为您提供较低分辨率的图像。我不希望 IE10- 出现在视网膜/高分辨率设备上。另外,在 JavaScript 中使用 CSS 检查不比使用原生窗口属性更奇怪吗?

哎呀,devicePixelRatio 浏览器支持甚至比分辨率规范还要好。 (见:http://caniuse.com/#feat=css-media-resolution

我想说它实际上使用起来非常安全,我们在每月访问量超过 1000 万的生产网站中使用它。按预期工作。

我唯一要更改的是函数名称,因为需要加载高分辨率图像在技术上并不意味着屏幕是视网膜。实际上,您甚至不需要进行数字检查,因为undefined > 1 的结果是false

function is_high_resolution_screen() {
  return window.devicePixelRatio > 1;
}

【讨论】:

  • window.devicePixelRatio 可以找到视网膜显示器,但如果目标是检测视网膜/高 dpi 显示器,那么 window.devicePixelRatio 是完全不可靠的(尝试例如。使用 Chrome,将缩放级别设置为高于 100% 的值,无论您使用哪种显示器,都会得到误报)
  • 是的,当然,但是浏览器仍然会从更高分辨率的图像中受益,因为你会有更多的像素来显示它们。如果在大多数情况下首选屏幕,这再次证明只是检查像素比而不是类型。此外,如果您在此处查看 TS 的评论:stackoverflow.com/questions/19689715/…,您可以看到他正在寻求了解何时提供高分辨率图像的最佳方式。这个(他的)解决方案正是这样做的。
  • mm.. 如果图像在响应式布局中具有通常的百分比大小或者是全屏背景怎么办?仅检查devicePixelRatio 不足以确保确实需要高清图像。您可以在不需要时轻松触发重高清图像的下载,至少您应该检查devicePixelRatio 和屏幕逻辑宽度/高度(这也不完美,因为两者的行为都不是标准的最新的浏览器,但它解决了更多的情况)
  • 是的,当然要视情况而定。如果您的图像是基于百分比大小的,那么您将需要比devicePixelRatio 更精致的东西是合乎逻辑的。但这不是最初的答案。在我正在处理的一个项目中,我们有根据浏览器大小调整大小的惰性图像。我们从 CDN 获得大小与我们需要的确切像素大小的图像。为了充分利用高分辨率显示器,我们将宽度乘以devicePixelRatio。这样,我们用图像像素填充每个设备屏幕像素。如果比率低于 1,您实际上可以获得较低分辨率的图像。 (缩小浏览器。)
【解决方案4】:

devicePixelRatio 根本不可靠。当您放大到 200% 时,window.devicePixelRatio 将返回 2,但您不在视网膜显示器上。

【讨论】:

  • 但是您的屏幕仍然能够渲染所有可用的额外像素。这就是为什么设备像素比是一个很棒的功能。
  • 同意李乐。在缩放 200% 时,当前 Chrome 返回原始值的两倍。也就是说,当您缩放时, devicePixelRatio 也会“缩放”。它不是检测缩放或视网膜支持的可靠值。
  • 好点李乐。尤其是当尝试使用这种技术使 HTML 画布在视网膜显示器上看起来正确时:developer.mozilla.org/en-US/docs/Web/API/Window/… 您实际上不能像 MDN 上所宣传的那样使用 devicePixelRatio,因为当用户手动放大时它会错误地缩放。用户缩放和视网膜显示需要有一个单独的设备比例变量
猜你喜欢
  • 2013-12-02
  • 2011-06-16
  • 2019-01-26
  • 1970-01-01
  • 2010-10-12
  • 1970-01-01
  • 2011-10-09
相关资源
最近更新 更多