Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect page zoom change with jQuery in Safari

I have a problem with Safari in a web application that contains a position:fixed element. When the page is zoomed out (smaller 100%) things break and would need to be fixed by calling a function. So I'd like to detect the user's zooming. I found this jQueryPlug-in a while ago:

http://mlntn.com/2008/12/11/javascript-jquery-zoom-event-plugin/

http://mlntn.com/demos/jquery-zoom/

It detects keyboard and mouse events that might lead to a page zoom level change. Fair enough. It works on current FF and IE but not on Safari. Any ideas what could be done to do something simmilar in current WebKit browsers?

like image 846
C.O. Avatar asked May 28 '11 17:05

C.O.


3 Answers

Differentiate between window resize, browser zoom change, and system dpi change

;(() => {
  const last = {
    devicePixelRatio: devicePixelRatio,
    innerWidth: innerWidth,
    innerHeight: innerHeight,
    outerWidth: outerWidth,
    outerHeight: outerHeight,
  }
      
  const browser = navigator.appVersion.includes('WebKit')
  
  const almostZero = n => n <= 1 && n >= -1
  
  window.addEventListener('resize', () => {
    if (last.devicePixelRatio !== devicePixelRatio) {
      if (browser ? almostZero(last.innerWidth - innerWidth) && almostZero(last.innerHeight - innerHeight)
          :almostZero(last.outerWidth - outerWidth) && almostZero(last.outerHeight - outerHeight)) {
        console.log('system wide dpi change')
      } else {
        console.log('browser level zoom change')
      }
    } else {
      console.log('window resize')
    }
    last.devicePixelRatio = devicePixelRatio
    last.innerWidth = innerWidth
    last.innerHeight = innerHeight
    last.outerWidth = outerWidth
    last.outerHeight = outerHeight
  })
})()

Works in Chrome & Firefox on Windows

like image 139
Monday Fatigue Avatar answered Sep 21 '22 13:09

Monday Fatigue


It's not a direct duplicate of this question since that deals with Mobile Safari, but the same solution will work.

When you zoom in, window.innerWidth is adjusted, but document.documentElement.clientWidth is not, therefore:

var zoom = document.documentElement.clientWidth / window.innerWidth;

Furthermore, you should be able to use the onresize event handler (or jQuery's .resize()) to check for this:

var zoom = document.documentElement.clientWidth / window.innerWidth;
$(window).resize(function() {
    var zoomNew = document.documentElement.clientWidth / window.innerWidth;
    if (zoom != zoomNew) {
        // zoom has changed
        // adjust your fixed element
        zoom = zoomNew
    }
});
like image 24
newtron Avatar answered Oct 15 '22 02:10

newtron


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

like image 2
Starx Avatar answered Oct 15 '22 02:10

Starx