如何在所有现代浏览器中检测页面缩放级别?虽然这篇文章讲述了如何在IE7和IE8中做到这一点,但我找不到一个好的跨浏览器解决方案。 Firefox存储页面缩放级别以供将来访问。在第一页加载,我能得到缩放级别吗?在某个地方,我读到当页面加载后发生缩放变化时,它是有效的。 有办法捕捉'缩放'事件吗?

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


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

当前回答

我使用了不同的方法,我创建了一个dom元素,高度和宽度固定为100px,位置固定,不透明度为0,基本上是一个隐藏元素。

然后我使用dom-to-image来捕获这个元素作为图像,这听起来可能有点过分,但我想要一个防弹的解决方案,我们已经在使用这个包了,然后验证输出图像宽度,如果它返回110,缩放是110%,这是非常准确的。

const ORIGINAL_ZOOM_SIZE = 100;
async function isValidateZoomLevel() {
    const base64Render = await domToImage({
      ref: hiddenElementReference,
    });
    const pixleRatio = Math.round(window.devicePixelRatio);
    return new Promise((resolve, reject) => {
      const img = new Image();
      img.onload = () => resolve(ORIGINAL_ZOOM_SIZE === img.width / pixleRatio && ORIGINAL_ZOOM_SIZE === (img.height / pixleRatio));
      img.onerror = reject;
      img.src = base64Render; 
    });
  }

其他回答

现在的情况比刚提出这个问题时还要糟糕。通过阅读我所能找到的所有回复和博客文章,这里有一个总结。我还设置了这个页面来测试所有这些测量缩放级别的方法。[↑断裂链接。存档副本→此处]。

编辑(2011-12-12):我添加了一个可以克隆的项目: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

这里是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>

对我来说,Chrome/Webkit,文档。width / jQuery(document).width()不能正常工作。当我把我的窗口变小,并放大到我的网站,这样水平滚动条出现,文档。width / jQuery(document).width()在默认缩放时不等于1。这是因为文档。宽度包括视口之外的部分文档。

使用窗口。innerWidth和window。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";
}

这可以检测比例。

html代码:

<body id="blog">

js:

function scale(){
return Math.round(100/(d.getElementById('blog').offsetWidth/d.getElementById('blog').getBoundingClientRect().width))/100;
}

缩放因子和比例不能相互混淆。用户控制“缩放”; “scale”是一个CSS转换。然而,11年零10个月前,understack指出:

基本上我想知道DIV在100%缩放时的尺寸。

这个是这样的。我将其与@media查询一起使用,以检测JavaScript中的设备缩放,即360x720可能应用0.5缩放;720 x360, 0.75。

var d=document;

I found this article enormously helpful. Huge thanks to yonran. I wanted to pass on some additional learning I found while implementing some of the techniques he provided. In FF6 and Chrome 9, support for media queries from JS was added, which can greatly simplify the media query approach necessary for determining zoom in FF. See the docs at MDN here. For my purposes, I only needed to detect whether the browser was zoomed in or out, I had no need for the actual zoom factor. I was able to get my answer with one line of JavaScript:

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

结合IE8+和Webkit解决方案(它们也是单行的),我能够在只有几行代码的情况下检测到绝大多数浏览器的缩放效果。

zoom = ( window.outerWidth - 10 ) / window.innerWidth

这就是你所需要的。