不能,实际上。
我最初的猜测是浏览器有意不公开这个功能,因为它们不想让我们与之对抗,或者基于这些信息做出善意但结果不好的决策。但我没有看到任何证据表明是这样。
StackOverflow 的答案 说明了跨浏览器兼容性有多么奇怪。 这段脚本 来自 2013 年,在我 Chrome 浏览器中有效,但在 Safari 中完全无效,并且在 Firefox 中报告错误。即使这段脚本有效,它也依赖于用户代理检测(这种方式不会存在太久)和一些非常奇怪的技巧。
因此,如果您发现我错了,请随时更正我,但我认为答案是我们现在无法正确地做到这一点。
有一个叫做视觉视口 API 的东西
我有点困惑。
- 规范是草案
- 支持图表 列出了很多支持情况
window.visualViewport
在 Firefox、Safari 和 Chrome(桌面版)中定义- 但是……
window.visualViewport.scale
在 Safari 和 Chrome 中始终为1
,在 Firefox 中为undefined
。换句话说:没用。
我不完全确定它是否应该准确地表示浏览器缩放级别,因为规范讨论了专门针对捏合缩放。因此,也许它只是不适用于桌面浏览器缩放级别。
这里的用例是什么?
一位朋友向我描述了这样的情况
他希望使用 CSS 网格来布局墓地(本身就很有趣),就像墓地的自上而下的蓝图一样。布局中包含大量信息。如果您“缩小”以使整个墓地都显示在一个页面上,则每个区域中的文本将太小而无法阅读(因为字体大小将调整为适合框/墓穴)。理想情况下,当浏览器缩小时,页面会隐藏该文本(可能是 .hide-text
类)。当放大到足够大时,文本将再次显示。
例如……
// Dunno if "resize" is best. I don't know what the "change zoom" event would be
window.visualViewport.addEventListener("resize", viewportHandler);
function viewportHandler(event) {
// NOTE: This doesn't actually work at time of writing
if (event.target.scale > 3) {
document.body.classList.remove("hide-text");
} else {
document.body.classList.add("hide-text");
}
}
有像素密度……
Ben Nadel 最近写了一篇博文:浏览器缩放如何影响 CSS 媒体查询和像素密度。
如果您查看 window.devicePixelRatio
并放大,则 Chrome 和 Firefox 中的像素密度会随着放大而增加,随着缩小而减少。理论上,您可以测试原始值(对于不同屏幕的用户,它可能从不同的位置开始),并使用该值的更改来猜测缩放比例。但是……在 Safari 中,它没有任何作用,也就是说,无论缩放比例如何,它都保持不变。此外,操作系统缩放级别会影响这里的情况,使其变得更加棘手;更不用说页面可能以放大的级别开始,这可能会从一开始就打乱整个计算。
好吧,我正要睡觉……然后我读了这篇文章……确定有一个答案。试了一下,然后意识到:“这做不到”。我试图测试屏幕宽度与窗口宽度的特定比率……这在 Chrome 的全屏模式下有效,但由于 IE 和 Firefox 都随窗口大小一起缩放屏幕大小,因此无法检测到差异。请原谅拼写错误和冗长的代码……现在是凌晨 2 点。
目前,我会通过监听目标容器内的鼠标和键盘事件来阻止浏览器缩放,并在这些事件中实现自定义缩放(例如 transform scale)。只有这样,您才能跨浏览器完全控制。
在我看来,在这种情况下,您希望使用实现 z 轴滚动/缩放机制的 JavaScript 库,而不是浏览器原生缩放。
是的,对于这个用例,我完全同意
我有一个类似的用例,试图弄清楚:许多较新的笔记本电脑具有高 dpi 屏幕和不错的分辨率,但它们在操作系统级别开箱即用地缩放内容,相当于小于 1024×768 的内容。试图找到一种方法来反转我们网络应用程序中某些组件的缩放比例,以便通常适合的内容仍然适合。
您是否找到了解决此问题的方案。我们遇到了同样的问题,之前从未遇到过这样的客户,但他们将所有内容都以 150% 的操作系统比例查看,这破坏了我们的布局。有没有办法限制它或防止它发生?
当您在平板电脑和笔记本电脑上使用捏合缩放时,
window.visualViewport.scale
会发生变化,这是一种不同的行为。不确定我是否正确理解了问题,但是您是否可以在 JS 中使用媒体查询来查看文档宽度是否与媒体查询匹配,以判断用户是否已放大?
例如
将浏览器窗口调整为 800px 宽。
在开发者工具中运行此 JS:
window.matchMedia('(min-width: 800px)')
(它应该为“matches”报告“true”。)放大。
运行相同的 JS。(它应该为“matches”报告“false”。)
要检测缩放量,您只需查看文档宽度与媒体查询最终再次匹配时的差异。
解决不知道浏览器缩放级别的第一种方法是使用 CSS 根据
radio
输入状态分配zoom
,这是一个快速示例,在选择25%
缩放级别时隐藏标题文本…………检查 CanIUse — Zoom 指出
zoom
**不受** Firefox、Opera Mini 和 KaiOS 的支持。但是,并非所有希望都破灭了,因为正如 StackOverflow — 使用 JavaScript 模拟浏览器缩放 上的一个答案所建议的那样,第二种方法是使用
transform: scale(/*...*/)
以及其他一些属性,例如……虽然这些示例没有检测缩放级别,但它们是可操作的解决方法,并且无需任何 JavaScript,此外,如果您想要 JavaScript 事件侦听器,将其添加到单选按钮输入中并不困难。
在花费数小时解决这个问题后,我不得不勉强得出结论,无法可靠地读取桌面上的缩放系数,因为 W3C 和浏览器供应商和谐地合作彻底搞砸了视口系统。在移动设备上,这是可能的。
首先,
window.visualViewport.scale
在支持的浏览器(基于 Chromium 的浏览器 + Firefox Android + Safari iOS)中为您提供了缩放级别,**但前提是您使用捏合缩放**。使用页面缩放时,它始终保持 1,正如您所看到的。显然。在不支持缩放的移动浏览器上,使用此计算,它有效
screen.width / ((window.visualViewport && window.visualViewport.width) || window.innerWidth)
在桌面浏览器上,就别想了。缩放不适用于页面缩放。
window.devicePixelRatio
确实适用于页面缩放,但不适用于捏合缩放。此外,您需要将该值除以系统的实际物理 DPR,而该值在 JavaScript 中找不到,因为这会泄露线索。对于您朋友的用例,我建议以下操作
1) 选择一个墓地地块作为参考元素,并读取其一次
offsetWidth
。2) 将此值与
window.innerWidth
进行比较,并确定用户是否已放大或缩小到足以保证显示或隐藏文本的程度。3) 理想情况下,在每次调整大小事件时重复此操作。不幸的是,调整大小事件在移动和桌面浏览器上都不可靠,因为为什么要让它们可靠呢?因此,也许还可以添加一个滚动事件,以及一个每两秒左右检查一次的轮询脚本。
我之前评论的补充:我提供的移动浏览器公式仅在您使用
meta width=device-width
时有效。我已经能够通过 JS 检测文本缩放有一段时间了:当发生文本缩放时,我会向标签添加一个类,以便我可以为页面设置样式,以便缩放后的文本仍然清晰易读。您可以在此处查看演示
https://www.useragentman.com/enable/hero-image-text-resize.php
当然,这可能会被滥用(例如,当文本缩放发生时,开发人员可以编写 CSS 使字体变小,这永远不应该这样做)——但如果使用得当,这可以修复文本缩放带来的许多 CSS 问题(在我的职业生涯中,我见过很多这样的问题)。
我很乐意收到关于这个库的反馈,该库可在 github 上获取
https://github.com/zoltan-dulac/text-zoom-resize
(在撰写本文时,我在页面顶部链接的 Enable 页面尚未提供正确的 npm 信息。它将很快更新,因此在此期间,只需使用 github.com 链接获取有关如何安装软件包的信息)。
我最近不得不找到一种方法来做到这一点,并找到了一种仅使用 CSS 的方法,该方法利用了
rem
的值在文本缩放期间会发生变化,而px
的值不会发生变化这一事实。因此,当
1rem
等于16px
时,类似以下内容…………在标准缩放下不会应用,但在 1170px 和 2336px 之间的 200% 缩放下会应用
JavaScript 可以检测浏览器的缩放级别吗?
在基于 Chromium 的浏览器中,答案是可以,只要版本支持 Window API
getScreenDetails
(从 Chrome v100(2022 年 3 月)开始可用——有关更多详细信息,请参阅 caniuse)。重大注意事项
只能异步检索。
需要用户接受“管理所有显示器上的窗口”的权限(显然这是一个相当大的问题)