如何在所有现代浏览器中检测页面缩放级别?虽然这篇文章讲述了如何在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>

当前回答

这个答案是基于user1080381的答案上devicePixelRatio返回错误的注释。

我发现在使用台式机、Surface Pro 3和Surface Pro 4时,这个命令在某些情况下也会错误地返回。

我发现它在我的桌面上是有效的,但是SP3和SP4给出的数字是不同的。

不过我注意到,SP3的缩放级别是我预期的1.5倍。当我查看显示设置时,SP3实际上被设置为150%,而不是我桌面上的100%。

因此,注释的解决方案应该是将返回的缩放级别除以当前所在机器的缩放比例。

我可以通过以下方法在Windows设置中获得比例:

ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_DesktopMonitor");
double deviceScale = Convert.ToDouble(searcher.Get().OfType<ManagementObject>().FirstOrDefault()["PixelsPerXLogicalInch"]);
int standardPixelPerInch = 96;
return deviceScale / standardPixelPerInch;

所以在我的SP3的情况下,这是这段代码在100%缩放时的样子:

devicePixelRatio = 1.5
deviceScale = 144
deviceScale / standardPixelPerInch = 1.5
devicePixelRatio / (deviceScale / standardPixelPerInch) = 1

乘以user1080381的原始答案中的100,然后将得到100(%)的缩放。

其他回答

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

编辑(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>

你可以试试

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

这将给你的浏览器缩放百分比水平在非视网膜显示。对于高DPI/视网膜显示器,它将产生不同的值(例如,Chrome和Safari为200,Firefox为140)。

捕获缩放事件,您可以使用

$(window).resize(function() { 
// your code 
});

在Internet Explorer 7、8和9中,这是有效的:

function getZoom() {
    var screen;

    screen = document.frames.screen;
    return ((screen.deviceXDPI / screen.systemXDPI) * 100 + 0.9).toFixed();
}

添加“+0.9”是为了防止舍入错误(否则,当浏览器缩放分别设置为105%和110%时,您将得到104%和109%)。

在IE6中不存在缩放,所以没有必要检查缩放。

这是针对Chrome的,在user800583回答之后…

我花了几个小时研究这个问题,并没有找到更好的方法,但是:

有16个“zoomLevel”而不是10个 当Chrome是全屏/最大化的比率是window. outerwidth /window。innerWidth,如果不是,比率似乎是(window. outerwidth -16)/window。innerWidth,但是第一种情况可以被第二种情况接近。

所以我想到了下面这些……

但是这种方法有局限性:例如,如果您在应用程序窗口中使用手风琴(快速放大和减小窗口的宽度),那么尽管缩放没有改变(可能outerWidth和innerWidth没有同时更新),但您将在缩放级别之间获得间隙。

var snap = function (r, snaps)
{
    var i;
    for (i=0; i < 16; i++) { if ( r < snaps[i] ) return i; }
};
var w, l, r;
w = window.outerWidth, l = window.innerWidth;
return snap((w - 16) / l,
            [ 0.29, 0.42, 0.58, 0.71, 0.83, 0.95, 1.05, 1.18, 1.38, 1.63, 1.88, 2.25, 2.75, 3.5, 4.5, 100 ],
);

如果你想要因子:

var snap = function (r, snaps, ratios)
{
    var i;
    for (i=0; i < 16; i++) { if ( r < snaps[i] ) return eval(ratios[i]); }
};
var w, l, r;
w = window.outerWidth, l = window.innerWidth;
return snap((w - 16) / l,
            [ 0.29, 0.42, 0.58, 0.71, 0.83, 0.95, 1.05, 1.18, 1.38, 1.63, 1.88, 2.25, 2.75, 3.5, 4.5, 100 ],
            [ 0.25, '1/3', 0.5, '2/3', 0.75, 0.9, 1, 1.1, 1.25, 1.5, 1.75, 2, 2.5, 3, 4, 5 ]
);

这对我来说在基于webkit的浏览器(Chrome, Safari)中非常有效:

function isZoomed() {
    var width, mediaQuery;

    width = document.body.clientWidth;
    mediaQuery = '(max-width: ' + width + 'px) and (min-width: ' + width + 'px)';

    return !window.matchMedia(mediaQuery).matches;
}

但在Firefox中似乎不能正常工作。

这也适用于WebKit:

var zoomLevel = document.width / document.body.clientWidth;