How do I get JavaScript to open a popup window on the current monitor
Asked Answered
C

8

22

Scenario:

  1. The user has two monitors.
  2. Their browser is open on the secondary monitor.
  3. They click a link in the browser which calls window.open() with a specific top and left window offset.
  4. The popup window always opens on their primary monitor.

Is there any way in JavaScript to get the popup window to open on the same monitor as the initial browser window (the opener)?

Cinque answered 11/9, 2008 at 21:6 Comment(4)
not a single one of these 'solutions' work for me. Did you find any way.Chemoreceptor
@Chemoreceptor i've provided a solution that works for me, answered in this post though: #6911638Caricaria
you should've posted it here instead. The other is a dup and this thread has more relevant context.Chemoreceptor
true, i only saw this question after posting my answer on the other thread - let me move my answer overCaricaria
S
22

You can't specify the monitor, but you can specify the position of the popup window as being relative to the where the click caused the window to popup.

Use the getMouseXY() function to get values to pass as the left and top args to the window.open() method. (the left and top args only work with V3 and up browsers).

window.open docs: http://www.javascripter.net/faq/openinga.htm

function getMouseXY( e ) {
    if ( event.clientX ) { // Grab the x-y pos.s if browser is IE.
        CurrentLeft = event.clientX + document.body.scrollLeft;
        CurrentTop  = event.clientY + document.body.scrollTop;
    }
    else {  // Grab the x-y pos.s if browser isn't IE.
        CurrentLeft = e.pageX;
        CurrentTop  = e.pageY;
    }  
    if ( CurrentLeft < 0 ) { CurrentLeft = 0; };
    if ( CurrentTop  < 0 ) { CurrentTop  = 0; };  

    return true;
}
Sneakbox answered 11/9, 2008 at 21:15 Comment(0)
G
19

Here is something I shamelessly reverse engineered from the Facebook oauth API. Tested on a primary and secondary monitor in Firefox/Chrome.

function popup_params(width, height) {
    var a = typeof window.screenX != 'undefined' ? window.screenX : window.screenLeft;
    var i = typeof window.screenY != 'undefined' ? window.screenY : window.screenTop;
    var g = typeof window.outerWidth!='undefined' ? window.outerWidth : document.documentElement.clientWidth;
    var f = typeof window.outerHeight != 'undefined' ? window.outerHeight: (document.documentElement.clientHeight - 22);
    var h = (a < 0) ? window.screen.width + a : a;
    var left = parseInt(h + ((g - width) / 2), 10);
    var top = parseInt(i + ((f-height) / 2.5), 10);
    return 'width=' + width + ',height=' + height + ',left=' + left + ',top=' + top + ',scrollbars=1';
}   

window.open(url, "window name", "location=1,toolbar=0," + popup_params(modal_width, modal_height));
Graeco answered 13/1, 2011 at 16:11 Comment(4)
what's the point of this line? var h = (a < 0) ? window.screen.width + a : a; It wasn't positioning the screen correctly for me with that line.Pufahl
On OS X this works for all monitor arrangements in firefox. Does not work for over-under monitor arrangements in Chrome (will correctly position horizontally but won't move vertically beyond the main monitor). Does not work for side-by-side arrangements in Safari (will correctly position vertically but won't move horizontally beyond the main monitor). For chrome and safari I don't think there's anything else to be done though, seems to be broswer limitations/bugs.Pufahl
This worked perfectly for me when trying to position the facebook Share dialog (I bet a lot of the people looking up this question are doing it for the same reason).Roughneck
@Pufahl I think that may be some browser returning screenX as -ve for the other screen in case of 2 screens. Didn't get why the top was divided by 2.5 though.Inconsistent
C
7
// Pops a window relative to the current window position
function popup(url, winName, xOffset, yOffset) {
  var x = (window.screenX || window.screenLeft || 0) + (xOffset || 0);
  var y = (window.screenY || window.screenTop || 0) + (yOffset || 0);
  return window.open(url, winName, 'top=' +y+ ',left=' +x))
}

Call it like the following and it will open on top of the current window

popup('http://www.google.com', 'my-win');

Or make it slightly offset

popup('http://www.google.com', 'my-win', 30, 30);

The point is that window.screenX/screenLeft give you the position in relationship to the entire desktop, not just the monitor.

window.screen.left would be the ideal candidate to give you the information you need. The problem is that it's set when the page is loaded and the user could move the window to the other monitor.

More research

A final solution to this problem (beyond just offsetting from the current window position) requires knowing the dimensions of the screen that the window is in. Since the screen object doesn't update as the user moves a window around, we need to craft our own way of detecting the current screen resolution. Here's what I came up with

/**
 * Finds the screen element for the monitor that the browser window is currently in.
 * This is required because window.screen is the screen that the page was originally
 * loaded in. This method works even after the window has been moved across monitors.
 * 
 * @param {function} cb The function that will be called (asynchronously) once the screen 
 * object has been discovered. It will be passed a single argument, the screen object.
 */
function getScreenProps (cb) {
    if (!window.frames.testiframe) {
      var iframeEl = document.createElement('iframe');
      iframeEl.name = 'testiframe';
      iframeEl.src = "about:blank";
      iframeEl.id = 'iframe-test'
      document.body.appendChild(iframeEl);
    }

    // Callback when the iframe finishes reloading, it will have the 
    // correct screen object
    document.getElementById('iframe-test').onload = function() {
      cb( window.frames.testiframe.screen );
      delete document.getElementById('iframe-test').onload;
    };
    // reload the iframe so that the screen object is reloaded
    window.frames.testiframe.location.reload();
};

So if you wanted to always open the window at the top left of whatever monitor the window is in, you could use the following:

function openAtTopLeftOfSameMonitor(url, winName) {
  getScreenProps(function(scr){
    window.open(url, winName, 'top=0,left=' + scr.left);
  })
}
Centering answered 24/1, 2011 at 20:46 Comment(1)
works in FF. seems like chrome doesn't care much about the left and top parameters.Chemoreceptor
A
3

Open centered window on current monitor, working also with Chrome:

function popupOnCurrentScreenCenter(url, title, w, h) {
    var dualScreenLeft = typeof window.screenLeft !== "undefined" ? window.screenLeft : screen.left;
    var dualScreenTop = typeof window.screenTop !== "undefined" ? window.screenTop : screen.top;

    var width = window.innerWidth ? window.innerWidth :
        document.documentElement.clientWidth ? document.documentElement.clientWidth : screen.width;
    var height = window.innerHeight ? window.innerHeight :
        document.documentElement.clientHeight ? document.documentElement.clientHeight : screen.height;

    var left = ((width / 2) - (w / 2)) + dualScreenLeft;
    var top = ((height / 2) - (h / 2)) + dualScreenTop;
    var newWindow =
        window.open(url, title, 'scrollbars=yes, width=' + w + ', height=' + h + ', top=' + top + ', left=' + left);

    // Puts focus on the newWindow
    if (window.focus) {
        newWindow.focus();
    }
}
Alodium answered 24/10, 2014 at 14:25 Comment(0)
D
0

If you know the resolution of each monitor, you could estimate this. A bad idea for a public website, but might be useful if you know (for some odd reason) that this scenario will always apply.

Relative position to the mouse (as said above) or to the original browser window could also be useful, Though you'd have to suppose the user uses the browser maximized (which is not necessarily true).

Dodiedodo answered 14/6, 2009 at 20:47 Comment(0)
C
0

I ran into this issue recently and finally found a way to position the pop up window on the screen that it's triggered from. Take a look at my solution on my github page here: https://github.com/svignara/windowPopUp

The trick is in using the window.screen object, which returns availWidth, availHeight, availLeft and availTop values (as well as width and height). For a complete list of the variables in the object and what these variables represent look at https://developer.mozilla.org/en-US/docs/DOM/window.screen.

Essentially, my solution finds the values of the window.screen whenever the trigger for the popup is clicked. This way I know for sure which monitor screen it's being clicked from. The availLeft value takes care of the rest. Here's how:

Basically if the first available pixel from the left (availLeft) is negative, that's telling us there is a monitor to the left of the "main" monitor. Likewise, if the first available pixel from left is greater than 0, this means one of 2 things:

  1. The monitor is to the right of the "main" monitor, OR
  2. There is some "junk" on the left side of the screen (possibly the application dock or windows start menu)

In either case you want the offset of your popup to start from after the available pixel from the left.

offsetLeft = availableLeft + ( (availableWidth - modalWidth) / 2 )
Caricaria answered 12/1, 2013 at 4:35 Comment(0)
A
0

Only user11153's version works with Chrome and dual screen. Here is its TypeScript version.

popupOnCurrentScreenCenter(url: string, title: string, w: number, h: number): Window|null {
    var dualScreenLeft = typeof window.screenLeft !== "undefined" ? window.screenLeft : (<any>screen).left;
    var dualScreenTop = typeof window.screenTop !== "undefined" ? window.screenTop : (<any>screen).top;

    var width = window.innerWidth ? window.innerWidth :
        document.documentElement.clientWidth ? document.documentElement.clientWidth : screen.width;
    var height = window.innerHeight ? window.innerHeight :
        document.documentElement.clientHeight ? document.documentElement.clientHeight : screen.height;

    var left = ((width / 2) - (w / 2)) + dualScreenLeft;
    var top = ((height / 2) - (h / 2)) + dualScreenTop;
    var newWindow =
        window.open(url, title, 'scrollbars=yes, width=' + w + ', height=' + h + ', top=' + top + ', left=' + left);

    // Puts focus on the newWindow
    if (window.focus && newWindow) {
        newWindow.focus();
    }
    return newWindow;
}
Audet answered 10/9, 2018 at 0:34 Comment(0)
R
-3

as long as you know the x and y position that falls on the particular monitor you can do:

var x = 0;
var y = 0;
var myWin = window.open(''+self.location,'mywin','left='+x+',top='+y+',width=500,height=500,toolbar=1,resizable=0');
Rectus answered 11/9, 2008 at 21:14 Comment(1)
How is the OP supposed to know x and y position? You can't assume there'll always be two monitors, or their resolution... This doesn't help.Centering

© 2022 - 2024 — McMap. All rights reserved.