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

und*_*ack 296 javascript browser zoom detection

  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>
Run Code Online (Sandbox Code Playgroud)

yon*_*ran 269

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

编辑(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:screen.width/媒体查询屏幕宽度(见下文)(利用screen.width使用设备像素但MQ宽度使用CSS像素的事实- 由于Quirksmode宽度)
  • FF3.6:没有已知的方法
  • FF4 +:媒体查询二进制搜索(见下文)
  • WebKit:https://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的宽度表说它是一个bug; innerWidth应该是CSS px).我们使用position:fixed元素来获取视口的宽度,包括滚动条所在的空间 ; document.documentElement.clientWidth排除此宽度.这在2011年的某个时候被打破了; 我知道无法再在Opera中获得缩放级别.
  • 其他:塞巴斯蒂安的Flash解决方案
  • 不可靠:收听鼠标事件并测量clientX中screenX/change的变化

这是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>
Run Code Online (Sandbox Code Playgroud)

  • 好消息,大家好!他们最终做到了!Vieport API!https://www.chromestatus.com/feature/5737866978131968我测试它,很棒的东西! (5认同)
  • Viewport API仅适用于缩放缩放; 如果你放大桌面它说比例是1. @Jason T Featheringham除了"歧视"之外还有其他理由想知道缩放级别.缩放是在域的所有页面上设置的,但您可能希望在游戏页面或扩展程序弹出窗口中以不同于帮助页面的方式处理它. (2认同)

use*_*381 51

你可以试试

var browserZoomLevel = Math.round(window.devicePixelRatio * 100);
Run Code Online (Sandbox Code Playgroud)

这将为您提供浏览器缩放百分比级别.

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

$(window).resize(function() { 
// your code 
});
Run Code Online (Sandbox Code Playgroud)

  • 支持高DPI屏幕的浏览器在使用此类显示器时不会产生预期结果,Safari也不会显示. (15认同)
  • 不能按预期工作:当浏览器未缩放时,它在带有视网膜的MacBook上的Chrome中返回200. (11认同)
  • `Math.round(window.devicePixelRatio * 100)` 适用于 Chrome、IE、Edge 和 Firefox。iMac 上的 Safari 始终返回 200。 (3认同)
  • 这在 Retina 显示屏上的 Chrome 上不起作用,因为默认值不是 1,而是 2。具有不同像素密度的不同屏幕应该提供不同的值。 (3认同)

小智 45

对我来说,对于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";
}
Run Code Online (Sandbox Code Playgroud)

  • 这在 Chrome 和 Edge 中有效,但是这两种浏览器都在outerWidth 中包含调试 (F12) 窗口,因此如果打开此窗口,您的结果将会有很大差异。 (3认同)
  • 嗯,window.outerWidth 也会随着缩放而改变。此外,并非每个操作系统上的窗口边框宽度都是 8 像素(即使在相同的操作系统上,设计也可能有所不同)。不过我建议减去 16,而不是 8,因为窗口边框有两次。另外,有些浏览器在其实际渲染窗口上有边框(如 FF),而有些浏览器则没有(Safari) - 但这也取决于您使用浏览器的操作系统(例如 Safari 在 Windows 上有边框)。备份初始innerWidth(例如在页面加载时)并使用它进行比较效果更好,但前提是初始缩放为100%... (2认同)

小智 16

我和我的同事使用了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);
Run Code Online (Sandbox Code Playgroud)

  • 从Chrome 45开始,这不再适用. (3认同)
  • 现在,此方法在 Firefox 29 中始终报告 svg.currentScale = 1。可能是因为它们根据缩放调整整个屏幕图形的大小,这是一个 [bug](https://bugzilla.mozilla.org/show_bug.cgi?id=1022006) 。IE11 在桌面上似乎也有同样的问题,屏幕高度调整为视口设备像素比,这非常糟糕。 (2认同)

小智 11

我发现这篇文章非常有帮助.非常感谢yonran.我想在实现他提供的一些技术时传递一些额外的学习知识.在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;
Run Code Online (Sandbox Code Playgroud)

将此与IE8 +和Webkit解决方案(也是单行)相结合,我能够通过仅几行代码检测绝大多数浏览器上的缩放.

  • 您能否提供一个如何使用媒体查询检测实际缩放的代码? (4认同)

小智 11

zoom = ( window.outerWidth - 10 ) / window.innerWidth
Run Code Online (Sandbox Code Playgroud)

这就是你所需要的.

  • 可能是为了滚动条。每个滚动条也不同,就像 iOS 中的滚动条要小得多。另外这个解决方案似乎仅适用于 chrome (3认同)
  • 如果用户有侧边栏(例如 FF 中的书签),则不起作用 (3认同)
  • 在Chrome上运行得很好,在FF上根本不起作用. (2认同)
  • 请考虑添加解释,尤其是在使用幻数时。 (2认同)

col*_*rco 8

您可以使用视觉视口 API

window.visualViewport.scale;
Run Code Online (Sandbox Code Playgroud)

它是标准的,可在桌面和移动设备上运行:浏览器支持

  • 此属性返回捏缩放的值,但不返回浏览器的缩放级别(CMD + '+')。 (23认同)
  • 看起来很方便,但默认情况下它在 Firefox 桌面中仍然处于禁用状态,并且从 2020 年 5 月 31 日起在 Internet Explorer 中不起作用。 (2认同)

kir*_*oid 7

基本上,我们有:

\n\n
    \n
  • window.devicePixelRatio它考虑了浏览器级缩放*以及系统缩放/像素密度。
    \n* 不考虑 Mac/Safari 上的 \xe2\x80\x94 缩放级别
  • \n
  • 媒体查询
  • \n
  • vw/ vhCSS 单位
  • \n
  • resize事件,在缩放级别更改时触发,导致窗口的有效大小发生变化
  • \n
\n\n

对于正常的用户体验来说这应该足够了。如果您需要检测缩放级别,这可能是 UI 设计不良的迹象。

\n\n

俯仰-缩放更难跟踪,目前不考虑。

\n

  • window.devicePixelRatio 是一个很好的答案,适用于最新版本的主要浏览器 - Chrome、Safari、FF、Edge、IE (2认同)

小智 6

截至2016年1月,我有一个解决方案.测试过Chrome,Firefox和MS Edge浏览器.

原理如下.收集相距很远的2个MouseEvent点.每个鼠标事件都带有屏幕和文档坐标.测量两个坐标系中2个点之间的距离.虽然由于浏览器家具,坐标系之间存在可变的固定偏移,但如果页面未缩放,则之间的距离应相同.指定"远离"(我把它设为12像素)的原因是可以检测到小的变焦变化(例如90%或110%).

参考:https: //developer.mozilla.org/en/docs/Web/Events/mousemove

脚步:

  1. 添加鼠标移动侦听器

    window.addEventListener("mousemove", function(event) {
        // handle event
    });
    
    Run Code Online (Sandbox Code Playgroud)
  2. 从鼠标事件中捕获4个测量值:

    event.clientX, event.clientY, event.screenX, event.screenY
    
    Run Code Online (Sandbox Code Playgroud)
  3. 测量客户端系统中2个点之间的距离d_c

  4. 测量屏幕系统中2个点之间的距离d_s

  5. 如果d_c!= d_s则应用缩放.两者之间的差异告诉你缩放量.

NB很少进行距离计算,例如,当您可以采样远离前一个的新鼠标事件时.

限制:假设用户将鼠标移动至少一点,并且在此之前缩放是不可知的.