Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get browser window position regardless of zoom

How can I get the browser window's left edge (including menu, border, caption, etc), without it being "fixed" to take into account the zoom level? (This question addresses the basic question, but does not consider zoom.).

window.screenLeft or window.screenX work fine on Chrome and Safari, but these report "fixed" values using IE6, IE8 and Firefox.

I have considered that I can get the screen's size more reliably, and perhaps determine the zoom factor using that or screen.deviceXDPI, but I am not sure how I would use that to correct the position.

(Some of you are probably wondering why I want to do this. It is because a training web site opens a browser window on the right hand side of the user's screen. The browser communicates with my application using the script tag hack. The application wants to resize itself so it fits exactly to the left of the browser window.)

EDIT

I should have mentioned two things:

  1. I am asking about the browser zooming that you can typically access from a View menu or by holding down Ctrl and turning your mouse wheel. Because most web pages are not well able to respond to changes in (for example) default font size without mucking up their layout, browsers implement zoom by scaling all measurements, including pixels. To keep things consistent, they also scale reported client and window size, mouse positions, etc. The trouble for me is that I want the real (unscaled) measures.
  2. I am looking for a JavaScript solution.
like image 832
Oliver Bock Avatar asked Oct 14 '10 01:10

Oliver Bock


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 do I check my browser zoom level?

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 change the page zoom on my screen size?

Select "Zoom," then click "Zoom In" to enlarge the website or "Zoom Out" to reduce its size. Each time "Zoom In" or "Zoom Out" is clicked, it will increase or reduce the magnification an additional level. Continue adjusting the "Zoom" option until the page is displayed to your liking.


1 Answers

Have you seen How to detect page zoom level in all modern browsers?

We can use window.devicePixelRatio or the binary search method suggested there to determined the pixel ratio. Then we scale window.screenX and window.screenY with this factor:

var X = window.screenX * pixelratio;
var Y = window.screenY * pixelratio;

I tested this in Firefox 48 and the window position changed with at most 2 pixels when changing the zoom level. Using window.devicePixelRatio or the binary search gave essentially the same results. I guess being 2 pixels off can be really annoying for graphical applications, but determining the zoom level seems to be messy.

<html>
  <head>
    <meta charset="UTF-8">
  </head>
  <body>
    <input id="button" type="button" value="Click me!"/>
    <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);
            }
        };

</script>
<script type="text/javascript">    
    var b = document.getElementById("button");
    b.onclick = function() {
        var pixelratio = mediaQueryBinarySearch(
	    'min--moz-device-pixel-ratio', '', 0, 6000, 25, .00001);

        console.log("devicePixelRatio:", window.screenX * window.devicePixelRatio, window.screenY * window.devicePixelRatio);
        console.log("binary search:", window.screenX * pixelratio, window.screenY * pixelratio);
        console.log(Math.abs(pixelratio - window.devicePixelRatio));
    }
  </script>
  </body>
</html>
like image 103
YellowBird Avatar answered Sep 21 '22 14:09

YellowBird