使用 JavaScript 在设备上检测视网膜支持的最佳方法是什么?

IT技术 javascript jquery retina-display
2021-02-18 11:54:52

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

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

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

4个回答

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

根据 w3.org:

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

查看全文

解析媒体查询文档

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

请注意,似乎MS Edge 在非整数值方面存在一些问题

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);
}
@BinaryFunt 对于 CSS,,我们正在检查不同的单位值 ( dpi, dppx, dpcm),min-resolution因为不同的浏览器支持不同的单位。javascript||是这样我们可以检查min-resolutionmin-device-pixel-ratio(再次因为不同的浏览器支持不同的媒体查询)。另外,有些浏览器不支持,window.matchMedia所以另||一种也是检查window.devicePixelRatio
2021-04-17 11:54:52
@NovitchiS 很有趣,根据规范“<resolution> 值是一个正的<number>紧跟一个单位标识符”(强调我的)所以看起来 MS 没有遵循规范。我会在答案中添加注释。
2021-04-22 11:54:52
今天在配备 Retina 的 MacBook 上检查了 isRetina() 函数 - 它不起作用。
2021-04-30 11:54:52
同时使用 CSS 'or' ( ,) 和 JS 'or' ( ||) 的原因是什么?
2021-05-09 11:54:52
@JomarSevillejo 在撰写本文时,Apple 仅有的视网膜显示器是 iPad、iPhone 和 iPod。这一行的唯一目的是检查浏览器的用户代理,无论如何都不应该信任它。这更像是一个例子。我建议使用该isHighDensity功能并根据您的需要更改分辨率媒体查询,而不是使用该isRetina功能。
2021-05-14 11:54:52

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

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

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

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

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

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

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

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

好点李乐。特别是当尝试使用这种技术使 HTML 画布在视网膜显示器上看起来正确时:developer.mozilla.org/en-US/docs/Web/API/Window/... 你实际上不能像 MDN 上宣传的那样使用 devicePixelRatio,因为当用户手动放大时,它会错误地缩放。用户缩放和视网膜显示需要一个单独的设备比例变量
2021-04-16 11:54:52
同意李乐的说法。在缩放 200% 时,当前 Chrome 返回原始值的两倍。也就是说,当您缩放时,devicePixelRatio 也会“缩放”。它不是检测缩放或视网膜支持的可靠值。
2021-04-18 11:54:52
但是您的屏幕仍然能够渲染所有可用的额外像素。这就是为什么设备像素比是一个很棒的功能。
2021-04-27 11:54:52