多监视器/双监视器系统上的window.open() -窗口在哪里弹出



在多监视器系统上使用javascript window.open()时,如何控制哪个监视器,或者在显示空间中弹出窗口打开的位置?在我看来,它似乎失去了控制,否则它的行为是随机的。

"window "的结果。"打开双屏幕"搜索显示了这个奇特的金块:双显示器和windows .open

"当用户点击一个链接,打开一个新窗口使用window.open。使窗口显示在与其"相同的监视器上。家长"

// Find Left Boundry of the Screen/Monitor
function FindLeftScreenBoundry()
{
    // Check if the window is off the primary monitor in a positive axis
    // X,Y                  X,Y                    S = Screen, W = Window
    // 0,0  ----------   1280,0  ----------
    //     |          |         |  ---     |
    //     |          |         | | W |    |
    //     |        S |         |  ---   S |
    //      ----------           ----------
    if (window.leftWindowBoundry() > window.screen.width)
    {
        return window.leftWindowBoundry() - (window.leftWindowBoundry() - window.screen.width);
    }
    // Check if the window is off the primary monitor in a negative axis
    // X,Y                  X,Y                    S = Screen, W = Window
    // 0,0  ----------  -1280,0  ----------
    //     |          |         |  ---     |
    //     |          |         | | W |    |
    //     |        S |         |  ---   S |
    //      ----------           ----------
    // This only works in Firefox at the moment due to a bug in Internet Explorer opening new windows into a negative axis
    // However, you can move opened windows into a negative axis as a workaround
    if (window.leftWindowBoundry() < 0 && window.leftWindowBoundry() > (window.screen.width * -1))
    {
        return (window.screen.width * -1);
    }
    // If neither of the above, the monitor is on the primary monitor whose's screen X should be 0
    return 0;
}
window.leftScreenBoundry = FindLeftScreenBoundry;

现在代码已经写好了,现在可以使用window了。打开,打开父窗口打开的监视器上的窗口。

window.open(thePage, 'windowName', 'resizable=1, scrollbars=1, fullscreen=0, height=200, width=650, screenX=' + window.leftScreenBoundry() + ' , left=' + window.leftScreenBoundry() + ', toolbar=0, menubar=0, status=1');

如果它成功地允许您在启动它的文档的同一屏幕上打开一个弹出窗口,那么通过类似的努力,您应该能够修改它以使其表现不同。

请注意,正如代码长度所暗示的那样,在jquery/javascript/浏览器中没有用于理解多个监视器的内置函数,只有双屏幕桌面只是一个放大的单笛卡尔平面,而不是两个离散的平面。

链接已断开。使用此waybackmachine链接

window.screenX将给出当前监视器屏幕的位置。

假设显示器宽度为1360

用于监视器1 window.screenX = 0;

window.screenX = 1360;

因此,通过在左侧位置加上window.screenX,在期望的位置弹出打开。

function openWindow() {
    var width = 650;
    var left = 200;
    left += window.screenX;
    window.open(thePage,'windowName','resizable=1,scrollbars=1,fullscreen=0,height=200,width=' + width + '  , left=' + left + ', toolbar=0, menubar=0,status=1');    
    return 0;
}

功能:

function PopupCenter(url, title, w, h, opts) {
   var _innerOpts = '';
   if(opts !== null && typeof opts === 'object' ){
       for (var p in opts ) {
           if (opts.hasOwnProperty(p)) {
               _innerOpts += p + '=' + opts[p] + ',';
           }
       }
   }
     // Fixes dual-screen position, Most browsers, Firefox
   var dualScreenLeft = window.screenLeft != undefined ? window.screenLeft : screen.left;
   var dualScreenTop = 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, _innerOpts + ' width=' + w + ', height=' + h + ', top=' + top + ', left=' + left);
// Puts focus on the newWindow
   if (window.focus) {
       newWindow.focus();
   }
}

用法:

PopupCenter('http://www.google.com','google.com','900','500', {toolbar:1, resizable:1, location:1, menubar:1, status:1}); 

以上解决方案都不能正常工作。

我试过了,它在chrome和firefox中工作得很好

var sY = screenY;
        if (sY < 0) {
            sY = 0;
        }
        var totalScreenWidth = (screenX + window.outerWidth + sY);
        if (totalScreenWidth > screen.width) {
            totalScreenWidth = totalScreenWidth / 2;
        } else {
            totalScreenWidth = 0;
        }
        windowobj.moveTo(totalScreenWidth + ((screen.width - h) / 2), ((screen.height - h) / 2));

但这也有问题,如果第二个监视器浏览器的一半在第一,另一半在第二。

如果有一个或多个附加显示,

screen.isExtendedtrue

window.getScreenDetails返回一个对象,包括屏幕数组,尺寸和位置。非主屏幕的left值将是将新窗口移动到该屏幕的目标。

const doSetup = async () => {
  const screenDetails = await window.getScreenDetails()
  if (screen.isExtended && screenDetails.screens.length > 1) {
    const newChildWindow = window.open(
      url,
      'New Child Window',
      `popup,width=${800},height=${600},left=0,top=0`
    )
    newChildWindow.moveTo(screenDetails.screens[1].left, 0)
  }
}

非常详细的解释:https://web.dev/multi-screen-window-placement/

基于javascript的解决方案由于安全原因无法工作。

我有另一个想法给你,为什么不使用chrome扩展来处理定位。(没有安全问题)当然,这只适用于chrome(也许这对你来说很好)。

背景:我们有相关的困难。内部web应用程序,可以在窗口中打开多个文档,并且需要放在其他监视器中。javascript不支持这个,出于安全原因,只有本地扩展才能正确地使用tabs/windows对象。

因此,我们已经创建了一个开源的chrome扩展做的正是:灵活的窗口位置跨多显示器设置。

在您的例子中,您可以很容易地为每个监视器定义一个规则,它将在哪里以及如何出现。您可以在chrome扩展的选项页面中这样做。(作为快捷方式,你可以安装后,直接使用)

chrome扩展名为"MultiWindow定位器"而且完全免费。你可以在chrome商店买到

在github项目chrome-multiwindow-定位器

中找到的实际源代码

声明:我是开源(MIT) github项目的维护者。如果有任何有趣的想法或评论,请在这里分享。

UPDATE 21/09/2020当我离开那家公司时,我不再是开源项目的维护者。也就是说,我不明白为什么会有人投反对票,因为浏览器不提供窗口。api允许您清楚地理解多个监视器,因为这是一个明显的安全限制/违反。这就是浏览器插件扩展帮助的地方,因为它们不是网页,它们可以访问额外的api,这些api可以精确地查找/列出监视器和窗口。它们遵循不同的安全上下文,因此具有额外的功能。并非所有浏览器都提供require扩展。支持多监视器的api。而Mozilla Firefox则没有。是的,Chrome和最新的MS Edge。经过这么多年的经验,我仍然100%没有纯javascript解决方案,唯一的方法是一个解决方案,涉及浏览器插件/扩展。

/**
 * Display popup window in the center of the screen.
 */
function popupWindow(url, title, w, h) {
  // Use window.screenX to center the window horizontally on multi-monitor 
  // setup. 
  var left = window.screenX + (screen.width / 2) - (w / 2);
  var top = (screen.height / 2) - (h / 2);
  return window.open(url, title, 'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=yes, copyhistory=no, width=' + w + ', height=' + h + ', top=' + top + ', left=' + left);
},

解决方案:

function openWindow( url, winnm, options)
{
    var wLeft = parseInt( typeof window.screenX != 'undefined' ? window.screenX : window.screenLeft );
    var left = 0;
    if( (result = /left=(d+)/g.exec(options)) ) {
        left = parseInt(result[1]);
    }
    if(options)
    {
       options = options.replace("left="+left,"left="+(parseInt(left) + wLeft));        
       w = window.open( url, winnm, options );
    }
    else
    {
       w = window.open( url, winnm );
    }
    if(w)
         w.focus();
    return w;
}

你只需要在js文件中替换:window。open to openWindow

最新更新