How to detect the Browsers Zoom Level / If the user changes Browser Zoom

[Update]: Example ZIP wasn’t working in deed. Thanks Unabus for the hint.
[Update]: jQuery no longer required. Changed initialisation method.
[Update]: Added ActionScript Source.
[Update]: Sorry, i posted the wrong version ( Thanks Ash for the hint ). The latest version now really supports Internet Explorer.

Every modern Web-Browsers gives you the possibility to zoom in/out the content of a website. If you zoom into the website this will easily enlarge the complete content for you. It includes all text and images. In many cases that makes it easier to read website at least for people with poor eyesight.
Now comes the BUT. Sometimes you have strange side-effects. For example when using the Flash plugin. If you don’t allow rescaling the flash content, which the flashplayer would otherwise easily does, you got some ugly sideeffects black borders or whatever. You may have your reasons for having none scalable flash ( if i don’t ran into this problem i would not write this, so at least i had my reasons – not only laziness ).

In many cases the side-effects don’t destroy your complete website and make it unuseable, but i would at least like to give the users a very small hint that their browser is zoomed and that this may effect the website layout ( i just recognize that this reminds a bit at the “This website is optimized for IE 6.0 and 1024×768 pixels” notices – how i hate this ). If i detect that the browser is zoomed if could also use other versions of my plugins/scripts/css/images/whatever, to make it look nice again – of couse the detection is the first step.

To detect this circumstance i wrote a little JavaScript because i don’t find any standard JavaScript-attribute or method which does this for me. There are also some scripts which attaches resize handler on HTML-elements (http://www.alistapart.com/articles/fontresizing/) , but it only detects the resizing itself and don’t notice when it is already resized or zoomed in this case.

As you maybe know i really love the Flash and JavaScript combination. So what my script does is to create a flash in the background and reads it stage-size (stage.stageHeight). If this differs from the originally setted flash size: et voilà: your client is zoomed (this does not for the iPhone, because there is not flash in safari allowed).

The script inserts a flash at the bottom right corner of the browsers viewport (10px * 10px by default). After the flash is initialised completly if will be moved to bottom left corner that only one pixel is still in the viewport, to be sure that the flash is still handled ( mozilla will not handle flash which is not at least visible in the viewport ).

Everything there is to do for you is to insert three two additional JavaScript files ( if you already use jQuery and swfObject, it’s only one additional ), set some configuration parameters and define your callback method. Just call the init-method and handle the result within the callback method. The init-method will return false if there is no flash are not the required flash is installed on the client. The following example will open an alert window as soon as the user changes the zoom level and when the zoom level is initally not “1″:

<script type="text/javascript" src="../javascript/swfobject.js"></script>
<script type="text/javascript" src="../javascript/swfZoomDetection.js"></script>
<script type="text/javascript">
  swfZoomDetection.init({
     'onZoomChange': function(obj){ alert(obj.scale) },
     'getInitIfOne': true,
     'initCallOnly': false,
     'frameRate': 25
  });
</script>

The configuration parameters are:
onZoomChange: This is the callback function, called when the users changes the zoom level of his browser. This function will also be called after the initialisation if the browser is already zoomed.

getInitIfOne: If the browser is not already zoomed ( zoom level = 1 ) the onZoomChange callback will not called after the initialisation by default. If you set this to true the callback function will also be called at beginning if the browser is not zoomed.

initCallOnly: If this is set to true the flash will be removed from DOM after if detects the first zoom level. After this no further zoom level changes by the user are detected.

frameRate: The flash will check “onEnterFrame” if the stageHeight and the zoom level has changed. So the more frames there are, the more precise you could check for updates. But i think at least a frameRate of 10 frames per second ( = 10 checks per second ) is more than precise enough.

Some further hints: Be aware you are using this script within a server environment and not from local filesystem, because of the flash player security model. The init-method should be called when the document is completly loaded. So use the $(document).ready() from jQuery, dojo.addOnload() from dojo, or the onLoad handler of the body-element.

  <body onLoad="loadFunction()">
     function loadFunction(){
         swfZoomDetection.init({ .... });
     }
  </body>

Download (2010/11/09): Simple Example (ZIP, 16kB)
Download (2010/08/24): swfZoomDetection (ZIP, 20kB)
Download (2010/02/12): swfZoomDetection AS Source (ZIP)

I hope this helps anybody.

cheers,
Sebastian