如何在所有现代浏览器中检测页面缩放级别?

IT技术 javascript browser zooming detection
2021-01-21 23:48:10
  1. 如何在所有现代浏览器中检测页面缩放级别?虽然这个线程告诉如何在 IE7 和 IE8 中做到这一点,但我找不到一个好的跨浏览器解决方案。

  2. Firefox 存储页面缩放级别以供将来访问。在第一页加载时,我能否获得缩放级别?页面加载发生缩放更改时我在某处读到它起作用

  3. 有没有办法捕获'zoom'事件?

我需要这个,因为我的一些计算是基于像素的,并且在缩放时它们可能会波动。


@tfl 给出的修改示例

此页面在缩放时会提示不同的高度值。[jsFiddle]

<html>
    <head>
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js" type="text/javascript"/></script>
    </head>
    <body>
        <div id="xy" style="border:1px solid #f00; width:100px;">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque sollicitudin tortor in lacus tincidunt volutpat. Integer dignissim imperdiet mollis. Suspendisse quis tortor velit, placerat tempor neque. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Praesent bibendum auctor lorem vitae tempor. Nullam condimentum aliquam elementum. Nullam egestas gravida elementum. Maecenas mattis molestie nisl sit amet vehicula. Donec semper tristique blandit. Vestibulum adipiscing placerat mollis.</div>
        <button onclick="alert($('#xy').height());">Show</button>
    </body>
</html>
6个回答

现在比第一次问这个问题时更混乱。通过阅读我能找到的所有回复和博客文章,这里是一个摘要。我还设置了这个页面来测试所有这些测量缩放级别的方法

编辑(2011-12-12):我添加了一个可以克隆的项目:https : //github.com/tombigel/detect-zoom

  • IE8 :(screen.deviceXDPI / screen.logicalXDPI或者,对于相对于默认缩放的缩放级别,screen.systemXDPI / screen.logicalXDPI
  • IE7 :(var body = document.body,r = body.getBoundingClientRect(); return (r.left-r.right)/body.offsetWidth;感谢这个例子这个答案
  • FF3.5 ONLY : screen.width/ 媒体查询屏幕宽度(见下文)(利用screen.width使用设备像素但 MQ 宽度使用 CSS 像素的事实——感谢Quirksmode 宽度
  • FF3.6:没有已知的方法
  • FF4+:媒体查询二分搜索(见下文)
  • WebKithttps : //www.chromestatus.com/feature/5737866978131968(感谢评论中的 Teo)
  • WebKit:使用 测量 div 的首选大小-webkit-text-size-adjust:none
  • WebKit :(自r72591损坏document.width / jQuery(document).width()(感谢上面的 Dirk van Oosterbosch)。要根据设备像素(而不是相对于默认缩放)获得比率,请乘以window.devicePixelRatio.
  • 旧的 WebKit?(未经证实):(parseInt(getComputedStyle(document.documentElement,null).width) / document.documentElement.clientWidth来自这个答案
  • Opera : document.documentElement.offsetWidth/ position:fixed; width:100%div 的宽度从这里开始Quirksmode 的宽度表说这是一个错误;innerWidth 应该是 CSS px)。我们使用 position:fixed 元素来获取视口的宽度,包括滚动条所在的空间document.documentElement.clientWidth 不包括此宽度。这在 2011 年的某个时候就被打破了;我知道没有办法在 Opera 中获得缩放级别了。
  • 其他来自 Sebastian 的 Flash 解决方案
  • 不可靠:监听鼠标事件并测量 screenX/clientX 的变化

这是 Firefox 4 的二进制搜索,因为我不知道它暴露的任何变量:

<style id=binarysearch></style>
<div id=dummyElement>Dummy element to test media queries.</div>
<script>
var mediaQueryMatches = function(property, r) {
  var style = document.getElementById('binarysearch');
  var dummyElement = document.getElementById('dummyElement');
  style.sheet.insertRule('@media (' + property + ':' + r +
                         ') {#dummyElement ' +
                         '{text-decoration: underline} }', 0);
  var matched = getComputedStyle(dummyElement, null).textDecoration
      == 'underline';
  style.sheet.deleteRule(0);
  return matched;
};
var mediaQueryBinarySearch = function(
    property, unit, a, b, maxIter, epsilon) {
  var mid = (a + b)/2;
  if (maxIter == 0 || b - a < epsilon) return mid;
  if (mediaQueryMatches(property, mid + unit)) {
    return mediaQueryBinarySearch(
        property, unit, mid, b, maxIter-1, epsilon);
  } else {
    return mediaQueryBinarySearch(
        property, unit, a, mid, maxIter-1, epsilon);
  }
};
var mozDevicePixelRatio = mediaQueryBinarySearch(
    'min--moz-device-pixel-ratio', '', a, b, maxIter, epsilon);
var ff35DevicePixelRatio = screen.width / mediaQueryBinarySearch(
    'min-device-width', 'px', 0, 6000, 25, .0001);
</script>
@yonran 很棒的插件!,但它在 IE9 中不起作用,它应该zoom: screen.deviceXDPI / screen.logicalXDPI,代替zoom: screen.systemXDPI / screen.logicalXDPI,
2021-03-10 23:48:10
非常好的工作,尽管这在 IE 8.0.7601.17514(最新)中对我不起作用。有没有机会将所有这些都包含在一个适用于所有浏览器的函数 getZoom() 中?也许也作为 jQuery 插件发布?干得好。
2021-03-13 23:48:10
Viewport API 仅适用于双指缩放;如果您在桌面上缩放,它会显示比例为 1。@Jason T Featheringham 除了“歧视”之外还有其他原因想要知道缩放级别。一个域的所有页面都设置了缩放,但您可能希望在游戏页面或扩展弹出窗口中以与在帮助页面中不同的方式处理它。
2021-03-19 23:48:10
@RobW,当我第一次为 Firefox 4 写这个时,Firefox 没有matchMedia. Paul Irish 也写了一个类似的 matchMedia polyfill,它是Modernizr 的一部分
2021-03-29 23:48:10
好消息,大家!他们终于做到了!Vieport API!chromestatus.com/feature/5737866978131968 我测试了,好东西!
2021-04-02 23:48:10

你可以试试

var browserZoomLevel = Math.round(window.devicePixelRatio * 100);

这将为您提供非视网膜显示器上的浏览器缩放百分比级别。对于高 DPI/retina 显示器,它会产生不同的值(例如,Chrome 和 Safari 为 200,Firefox 为 140)。

要捕捉缩放事件,您可以使用

$(window).resize(function() { 
// your code 
});
完美运行,也适用于移动设备。看看什么移动设备有什么也很有趣devicePixelRatio这也极大地帮助了我在缩放事件发生或初始值发生变化时将元素切换fixedabsolute定位元素devicePixelRatio完美的!谢谢!!
2021-03-11 23:48:10
这在 Retina 显示器上的 Chrome 上不起作用,因为默认值不是 1,而是 2。具有不同像素密度的不同屏幕应该提供不同的值。
2021-03-11 23:48:10
支持高 DPI 屏幕的浏览器在使用这种显示时不会给出预期的结果,无论显示如何,Safari 也不会。
2021-03-27 23:48:10
没有按预期工作:当浏览器未缩放时,它在带有视网膜的 MacBook 上的 Chrome 中返回 200。
2021-03-29 23:48:10
Math.round(window.devicePixelRatio * 100)适用于 Chrome、IE、Edge 和 Firefox。iMac 上的 Safari 总是返回 200。
2021-03-30 23:48:10

对我来说,对于 Chrome/Webkit,document.width / jQuery(document).width()不起作用。当我将窗口变小并放大我的站点以显示水平滚动条document.width / jQuery(document).width()时,默认缩放比例不等于 1。这是因为document.width包括视口之外的部分文档。

使用window.innerWidthwindow.outerWidth工作。出于某种原因,在 Chrome 中,outerWidth 以屏幕像素为单位,innerWidth 以 css 像素为单位。

var screenCssPixelRatio = (window.outerWidth - 8) / window.innerWidth;
if (screenCssPixelRatio >= .46 && screenCssPixelRatio <= .54) {
  zoomLevel = "-4";
} else if (screenCssPixelRatio <= .64) {
  zoomLevel = "-3";
} else if (screenCssPixelRatio <= .76) {
  zoomLevel = "-2";
} else if (screenCssPixelRatio <= .92) {
  zoomLevel = "-1";
} else if (screenCssPixelRatio <= 1.10) {
  zoomLevel = "0";
} else if (screenCssPixelRatio <= 1.32) {
  zoomLevel = "1";
} else if (screenCssPixelRatio <= 1.58) {
  zoomLevel = "2";
} else if (screenCssPixelRatio <= 1.90) {
  zoomLevel = "3";
} else if (screenCssPixelRatio <= 2.28) {
  zoomLevel = "4";
} else if (screenCssPixelRatio <= 2.70) {
  zoomLevel = "5";
} else {
  zoomLevel = "unknown";
}
无论如何输出 0 对我来说(2017 年 2 月)。
2021-03-11 23:48:10
switch 语句可能比许多 if else 语句更好。
2021-03-19 23:48:10
好吧,window.outerWidth 也随着缩放而改变。此外,并非在每个操作系统上,窗口边框宽度都是 8 像素(即使在相同的操作系统上,设计也可能有所不同)。但是我建议减去 16,而不是 8,因为您有两次窗口边框。此外,某些浏览器在其实际渲染窗口(如 FF)上有边框,而有些则没有(Safari)——但这也取决于您使用浏览器的操作系统(例如,Safari 在 Windows 上有边框)。备份初始的innerWidth(例如在页面加载时)并使用它来比较效果更好,但前提是初始缩放为100%......
2021-03-21 23:48:10
非常好。如果您只需要知道它是否在 Chrome 中缩放:isZoomed = (screenCssPixelRatio < .98 || screenCssPixelRatio > 1.02)
2021-03-23 23:48:10
它不起作用:刚刚在 Mac 上的 Chrome 上进行了测试,无论缩放级别如何,它始终返回相同的比例
2021-04-03 23:48:10

我和我的同事使用了https://github.com/tombigel/detect-zoom 中的脚本此外,我们还动态创建了一个 svg 元素并检查其 currentScale 属性。它适用于 Chrome,可能也适用于大多数浏览器。在 FF 上,“仅缩放文本”功能必须关闭。大多数浏览器支持SVG 在撰写本文时,已在 IE10、FF19 和 Chrome28 上进行测试。

var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
svg.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
svg.setAttribute('version', '1.1');
document.body.appendChild(svg);
var z = svg.currentScale;
... more code ...
document.body.removeChild(svg);
此方法现在在 Firefox 29 中总是报告 svg.currentScale = 1。可能是因为它们根据缩放调整了整个屏幕图形的大小,这是一个错误IE11 在桌面上似乎有同样的问题,屏幕高度调整到视口 devicePixelRatio,这很糟糕。
2021-03-16 23:48:10

我发现这篇文章非常有帮助。非常感谢永然。我想传递一些我在实施他提供的一些技术时发现的额外知识。在 FF6 和 Chrome 9 中,增加了对来自 JS 的媒体查询的支持,这可以大大简化确定 FF 中缩放所需的媒体查询方法。此处查看 MDN 上的文档出于我的目的,我只需要检测浏览器是放大还是缩小,我不需要实际的缩放系数。我能够用一行 JavaScript 得到我的答案:

var isZoomed = window.matchMedia('(max--moz-device-pixel-ratio:0.99), (min--moz-device-pixel-ratio:1.01)').matches;

将其与同样是单行的 IE8+ 和 Webkit 解决方案相结合,我只需几行代码就能够检测到绝大多数浏览器点击我们的应用程序的缩放。

尝试仅使用“(width: <X>px) and (height: <Y>px)”,其中 <X> 和 <Y> 分别是 window.innerWidth 和 window.innerHeight。它甚至适用于非常少量的缩放。也适用于 Safari。
2021-03-10 23:48:10
codepen.io/anon/pen/LgrGjJ展示了使用媒体查询的二分搜索,但这与查询相同devicePixelRatio:它考虑了显示缩放。
2021-03-12 23:48:10
您能否提供一个如何使用媒体查询检测实际缩放的代码?
2021-03-17 23:48:10
在 macbook pro 等视网膜设备上始终报告为真。
2021-04-04 23:48:10
@max 你能提供一个 JSFIddle 或示例代码,说明它是如何组合在一起的吗?
2021-04-05 23:48:10