Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Catch browser's "zoom" event in JavaScript

People also ask

Can JavaScript detect the browser zoom level?

Method 1: Using outerWidth and innerWidth Property: It is easier to detect the zoom level in webkit browsers like Chrome and Microsoft Edge. This method uses the outerWidth and innerWidthproperties, which are the inbuilt function of JavaScript.

How can we check page zoom level in all modern browsers?

One way to detect the browser zoom level is to use the window. devicePixelRatio property. When we zoom in or out, the resize event will be triggered.

How do I check my browser zoom level in Chrome?

Click the three vertical dots in the top-right corner of Chrome and then select “Settings.” Click “Advanced” and then select the “Privacy and Security” option. Scroll down and click “Site Settings.” Now, locate the “Zoom Levels” option. In this menu, you can view the custom zoom levels you've set for any given website.


There's no way to actively detect if there's a zoom. I found a good entry here on how you can attempt to implement it.

I’ve found two ways of detecting the zoom level. One way to detect zoom level changes relies on the fact that percentage values are not zoomed. A percentage value is relative to the viewport width, and thus unaffected by page zoom. If you insert two elements, one with a position in percentages, and one with the same position in pixels, they’ll move apart when the page is zoomed. Find the ratio between the positions of both elements and you’ve got the zoom level. See test case. http://web.archive.org/web/20080723161031/http://novemberborn.net/javascript/page-zoom-ff3

You could also do it using the tools of the above post. The problem is you're more or less making educated guesses on whether or not the page has zoomed. This will work better in some browsers than other.

There's no way to tell if the page is zoomed if they load your page while zoomed.


Lets define px_ratio as below:

px ratio = ratio of physical pixel to css px.

if any one zoom The Page, the viewport pxes (px is different from pixel ) reduces and should be fit to The screen so the ratio (physical pixel / CSS_px ) must get bigger.

but in window Resizing, screen size reduces as well as pxes. so the ratio will maintain.

zooming: trigger windows.resize event --> and change px_ratio

but

resizing: trigger windows.resize event --> doesn’t change px_ratio

//for zoom detection
px_ratio = window.devicePixelRatio || window.screen.availWidth / document.documentElement.clientWidth;

$(window).resize(function(){isZooming();});

function isZooming(){
    var newPx_ratio = window.devicePixelRatio || window.screen.availWidth / document.documentElement.clientWidth;
    if(newPx_ratio != px_ratio){
        px_ratio = newPx_ratio;
        console.log("zooming");
        return true;
    }else{
        console.log("just resizing");
        return false;
    }
}

The key point is difference between CSS PX and Physical Pixel.

https://gist.github.com/abilogos/66aba96bb0fb27ab3ed4a13245817d1e


Good news everyone some people! Newer browsers will trigger a window resize event when the zoom is changed.


I'm using this piece of JavaScript to react to Zoom "events".
It polls the window width. (As somewhat suggested on this page (which Ian Elliott linked to): http://novemberborn.net/javascript/page-zoom-ff3 [archive])

Tested with Chrome, Firefox 3.6 and Opera, not IE.

Regards, Magnus

var zoomListeners = [];

(function(){
  // Poll the pixel width of the window; invoke zoom listeners
  // if the width has been changed.
  var lastWidth = 0;
  function pollZoomFireEvent() {
    var widthNow = jQuery(window).width();
    if (lastWidth == widthNow) return;
    lastWidth = widthNow;
    // Length changed, user must have zoomed, invoke listeners.
    for (i = zoomListeners.length - 1; i >= 0; --i) {
      zoomListeners[i]();
    }
  }
  setInterval(pollZoomFireEvent, 100);
})();

This works for me:

        var deviceXDPI = screen.deviceXDPI;
        setInterval(function(){
            if(screen.deviceXDPI != deviceXDPI){
                deviceXDPI = screen.deviceXDPI;
                ... there was a resize ...
            }
        }, 500);

It's only needed on IE8. All the other browsers naturally generate a resize event.


There is a nifty plugin built from yonran that can do the detection. Here is his previously answered question on StackOverflow. It works for most of the browsers. Application is as simple as this:

window.onresize = function onresize() {
  var r = DetectZoom.ratios();
  zoomLevel.innerHTML =
    "Zoom level: " + r.zoom +
    (r.zoom !== r.devicePxPerCssPx
        ? "; device to CSS pixel ratio: " + r.devicePxPerCssPx
        : "");
}

Demo


Although this is a 9 yr old question, the problem persists!

I have been detecting resize while excluding zoom in a project, so I edited my code to make it work to detect both resize and zoom exclusive from one another. It works most of the time, so if most is good enough for your project, then this should be helpful! It detects zooming 100% of the time in what I've tested so far. The only issue is that if the user gets crazy (ie. spastically resizing the window) or the window lags it may fire as a zoom instead of a window resize.

It works by detecting a change in window.outerWidth or window.outerHeight as window resizing while detecting a change in window.innerWidth or window.innerHeight independent from window resizing as a zoom.

//init object to store window properties
var windowSize = {
  w: window.outerWidth,
  h: window.outerHeight,
  iw: window.innerWidth,
  ih: window.innerHeight
};

window.addEventListener("resize", function() {
  //if window resizes
  if (window.outerWidth !== windowSize.w || window.outerHeight !== windowSize.h) {
    windowSize.w = window.outerWidth; // update object with current window properties
    windowSize.h = window.outerHeight;
    windowSize.iw = window.innerWidth;
    windowSize.ih = window.innerHeight;
    console.log("you're resizing"); //output
  }
  //if the window doesn't resize but the content inside does by + or - 5%
  else if (window.innerWidth + window.innerWidth * .05 < windowSize.iw ||
    window.innerWidth - window.innerWidth * .05 > windowSize.iw) {
    console.log("you're zooming")
    windowSize.iw = window.innerWidth;
  }
}, false);

Note: My solution is like KajMagnus's, but this has worked better for me.