Testing for multiple screens with javascript
Asked Answered
D

7

11

Is it possible to tell if the user of a website is using multiple monitors? I need to find the position of a popup but it's quite likely the user will have a multiple monitor setup. Whilst window.screenX etc. will give the position of the browser window it's useless for multiple monitors.

Demona answered 26/9, 2008 at 16:13 Comment(3)
Popups suck. But if you absolutely must use them, then position them relative to their parent window - DO NOT use absolute coordinates.Shove
@Shove hi, could you please clarify why shouldn't we use absolute coordinates when opening new popups? It will be very helpful for me.Haight
That's probably a suitable topic for a completely separate question, @Haight - but the short answer is that there's a reasonable chance that you're going to position the popup somewhere that's inconvenient for me. I frequently have a browser window open in the right half of my secondary monitor which is larger than my primary monitor and positioned to its right; if you don't take this into account, there's a very good chance you're gonna put your popup over some other app or even off-screen.Shove
R
6

I didn't find the answer I needed anywhere on StackOverflow, so responding late to the several related threads here. The solution is, first, check for secondary display with window.screen.isExtended. Then await window.getScreenDetails(), which returns an object that includes an array of screens.

Very thorough explanation here: https://web.dev/multi-screen-window-placement/

Radiotherapy answered 21/6, 2022 at 20:45 Comment(0)
T
1

I do not believe that it is possible right now; however js is becoming more popular for desktop use in widgets in addition to web development and that would be an excellent feature to request for a future version

Tetramethyldiarsine answered 26/9, 2008 at 16:17 Comment(1)
I wonder if it's something a project like Gears might implement?Demona
L
1

This is an overly complicated solution. I'd highly recommend refactoring this - it's not been used on a production site, only as a quick 'proof of concept' to myself.

Right, caveats over.

I've first assumed that the user might not have a dual monitor setup, but they might have a really big monitor and so the same functionality could be applied anyway.

var newWindow,
    screenSpaceLeft = window.screenX,
    screenSpaceTop = window.screenY,
    screenSpaceRight = screen.availWidth - (window.screenX + window.outerWidth),
    screenSpaceBottom = screen.availHeight - (window.screenY + window.outerHeight),
    minScreenSpaceSide = 800,
    minScreenSpaceTop = 600,
    screenMargin = 8,

    width = (screen.availWidth / 2.05),
    height = screen.availHeight,
    posX = (screen.availWidth / 2),
    posY = 0;

e.preventDefault();

if (screenSpaceRight > screenSpaceLeft && screenSpaceRight > screenSpaceTop && screenSpaceRight > screenSpaceBottom && screenSpaceRight > minScreenSpaceSide) {
    if (width > screenSpaceRight) {
        width = screenSpaceRight - screenMargin;
    }
    if (posX < (screen.availWidth - screenSpaceRight)) {
        posX = window.screenX + window.outerWidth + screenMargin;
    }
} else if (screenSpaceLeft > screenSpaceRight && screenSpaceLeft > screenSpaceTop && screenSpaceLeft > screenSpaceBottom && screenSpaceLeft > minScreenSpaceSide) {
    if (width > screenSpaceLeft) {
        width = screenSpaceLeft - screenMargin;
    }

    posX = 0;
} else if (screenSpaceTop > screenSpaceRight && screenSpaceTop > screenSpaceLeft && screenSpaceTop > screenSpaceBottom && screenSpaceTop > minScreenSpaceTop) {
    posX = 0;
    posY = 0;
    width = screen.availWidth;
    height = (screen.availHeight / 2.05);
    if (height > screenSpaceTop) {
        height = screenSpaceTop - screenMargin;
    }
} else if (screenSpaceBottom > screenSpaceRight && screenSpaceBottom > screenSpaceLeft && screenSpaceBottom > screenSpaceTop && screenSpaceBottom > minScreenSpaceTop) {
    posX = 0;
    width = screen.availWidth;
    if (window.screenY + window.outerHeight + screenMargin > (screen.availHeight / 2)) {
        posY = window.screenY + window.outerHeight + screenMargin;
    } else {
        posY = (screen.availHeight / 2);
    }
    height = (screen.availHeight / 2.05);
    if (height > screenSpaceBottom) {
        height = screenSpaceBottom - screenMargin;
    }
}

newWindow = window.open(this.href, "_blank", "width=" + width + ",height=" + height + ",location=yes,menubar=no,resizable=yes,scrollbars=yes,status=yes,menubar=yes,top=" + posY + ",left=" + posX);

It checks how much available screen space there is, and if a minimum amount if available (800 x 600), it opens the window there. If there isn't enough space, it overlays the window on the right hand side of the screen, taking up just about half of it.

Notes:

First, it should be altered to find out where the maximum amount of space is rather than just arbitarily search left, right, top, bottom.

Second, I suspect that in some places where screen.availHeight has been used, screen.height should be used instead. Likewise for width. This is because we're not overly interested in where the taskbar is when deciding if the user has a second monitor or not (or a lot of space on the screen).

Third, it won't work in IE < 8. This can easily be rectified by using screenLeft and screenTop rather than screenX/screenY where appropriate.

Fourth, the code is messy and could be made to look a lot more elegant than it does. I make no apologies for this. However, you should NOT use such awful, unmaintainable JS anywhere and it NEEDS to be rewritten. I've only placed it here because it's in my train of thought at the moment and I'll most likely forget to post a good solution here when I write this properly as it won't happen for a few months.

Right. There you go. I accept no responsibility for making your javascript horrible, ugly and downright difficult to do anything with. :)

Lebel answered 23/1, 2014 at 10:25 Comment(0)
G
0

I found this as a solution that someone has used... I do not see why you couldn't trust it.

[if the width is greater then (Height/3) * 4 > (Screen.Width) THEN]

[User has dual monitor]

[End If]

Grossman answered 26/9, 2008 at 16:19 Comment(4)
Uh... I stack my screens. Height > Width. Neither screen has the same width, so if you were hugging the max-width you would end up off-screen beyond a certain height. Not to mention two-above, one below configurations.Shove
Also, lots of monitors have wider aspect-ratios than 4:3Germinal
Some machines (my own) are set up as two seperate desktops so the height and width are only returned for the screen the browser is on.Demona
You could have a high res primary mon, and a low res secondary mon. That solution is no good.Bucovina
R
0

You can't do that. You could position the popup centered on the parent window however. I think it's a better idea to show a "div" as dialog in the middle of your website, because the chance that this is popup blocked is smaller and it's IMO less annoying.

Rodd answered 26/9, 2008 at 16:19 Comment(0)
S
0

What about the size of the screen? Multiple screens have usually a great size. Just check the sizes and decide if it's reasonable to be on just one or more screens.

Stargell answered 26/9, 2008 at 16:19 Comment(0)
C
0

You could make a well-educated guess with JavaScript's screen.width (.availWidth) and screen.height (.availHeight).

My idea was to assume (!) that monitors in general follow a certain ratio, whereas the .[avail]width should be outside of it because the screen is duplicated only in terms of width, but not height.

Writing this answer, it sounds like a severe hack though. Nothing I would really rely on.

Chiffonier answered 26/9, 2008 at 16:22 Comment(1)
This will not work. availwith and availHeight tell you based on the current monitor. If the browser window is on the second monitor, it can be inferred from availTop and availLeft, but if the browser window is on the primary monitor, then those properties will not be able to tell you a second monitor actually exists.Fiveandten

© 2022 - 2024 — McMap. All rights reserved.