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

2022-01-29 00:00:00 zooming browser javascript detection

  1. 如何在所有现代浏览器中检测页面缩放级别?虽然这个 thread 告诉了如何去做在IE7和IE8中,找不到好的跨浏览器解决方案.

  2. Firefox 存储页面缩放级别以供将来访问.在第一页加载时,我可以获得缩放级别吗?当页面加载后发生缩放变化时,我在某处读过它.

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

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

<小时>

@tfl 给出的修改示例

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

<html><头><script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js" type="text/javascript"/></script></头><身体><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.整数 dignissim imperdiet mollis.Suspendisse quis tortor velit,placerat tempor neque.Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.Praesent bibendum actor lorem vitae tempor.Nullam condimentum aliquam elementum.Nullam 妊娠原素.Maecenas mattis molestie nisl 坐在 amet 车辆上.Donec semper tristique blandit.</div><button onclick="alert($('#xy').height());">显示</button></身体></html>

解决方案

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

编辑(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+:媒体查询二分搜索(见下文)
  • WebKit:https://www.chromestatus.com/feature/5737866978131968(感谢评论中的 Teo)
  • WebKit:使用 -webkit-text-size-adjust:none 测量 div 的首选大小.
  • 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 的宽度;宽度:100% 格.从这里 (Quirksmode 的宽度表 说这是一个错误;innerWidth 应该是 CSS px).我们使用 position:fixed 元素来获取视口的宽度包括滚动条所在的空间;document.documentElement.clientWidth 不包括此宽度.这自 2011 年的某个时候就被打破了;我再也无法在 Opera 中获得缩放级别了.
  • 其他:Sebastian 的 Flash 解决方案
  • 不可靠:监听鼠标事件并测量 screenX 的变化/clientX 的变化

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

<style id=binarysearch></style><div id=dummyElement>用于测试媒体查询的虚拟元素.</div><脚本>var mediaQueryMatches = 函数(属性,r){var style = document.getElementById('binarysearch');var dummyElement = document.getElementById('dummyElement');style.sheet.insertRule('@media (' + property + ':' + r +') {#dummyElement ' +'{text-decoration: underline} }', 0);var 匹配 = getComputedStyle(dummyElement, null).textDecoration== '下划线';style.sheet.deleteRule(0);返回匹配;};var mediaQueryBinarySearch = 函数(属性、单位、a、b、maxIter、epsilon) {变种中间 = (a + b)/2;if (maxIter == 0 || b - a 

  1. How can I detect the page zoom level in all modern browsers? While this thread tells how to do it in IE7 and IE8, I can't find a good cross-browser solution.

  2. Firefox stores the page zoom level for future access. On the first page load, would I be able to get the zoom level? Somewhere I read it works when a zoom change occurs after the page is loaded.

  3. Is there a way to trap the 'zoom' event?

I need this because some of my calculations are pixel-based and they may fluctuate when zoomed.


Modified sample given by @tfl

This page alerts different height values when zoomed. [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>

解决方案

Now it's an even bigger mess than it was when this question was first asked. From reading all the responses and blog posts I could find, here's a summary. I also set up this page to test all these methods of measuring the zoom level.

Edit (2011-12-12): I've added a project that can be cloned: https://github.com/tombigel/detect-zoom

  • IE8: screen.deviceXDPI / screen.logicalXDPI (or, for the zoom level relative to default zoom, screen.systemXDPI / screen.logicalXDPI)
  • IE7: var body = document.body,r = body.getBoundingClientRect(); return (r.left-r.right)/body.offsetWidth; (thanks to this example or this answer)
  • FF3.5 ONLY: screen.width / media query screen width (see below) (takes advantage of the fact that screen.width uses device pixels but MQ width uses CSS pixels--thanks to Quirksmode widths)
  • FF3.6: no known method
  • FF4+: media queries binary search (see below)
  • WebKit: https://www.chromestatus.com/feature/5737866978131968 (thanks to Teo in the comments)
  • WebKit: measure the preferred size of a div with -webkit-text-size-adjust:none.
  • WebKit: (broken since r72591) document.width / jQuery(document).width() (thanks to Dirk van Oosterbosch above). To get ratio in terms of device pixels (instead of relative to default zoom), multiply by window.devicePixelRatio.
  • Old WebKit? (unverified): parseInt(getComputedStyle(document.documentElement,null).width) / document.documentElement.clientWidth (from this answer)
  • Opera: document.documentElement.offsetWidth / width of a position:fixed; width:100% div. from here (Quirksmode's widths table says it's a bug; innerWidth should be CSS px). We use the position:fixed element to get the width of the viewport including the space where the scrollbars are; document.documentElement.clientWidth excludes this width. This is broken since sometime in 2011; I know no way to get the zoom level in Opera anymore.
  • Other: Flash solution from Sebastian
  • Unreliable: listen to mouse events and measure change in screenX / change in clientX

Here's a binary search for Firefox 4, since I don't know of any variable where it is exposed:

<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>

相关文章