【问题标题】:window.open() on a multi-monitor/dual-monitor system - where does window pop up?多显示器/双显示器系统上的 window.open() - 窗口在哪里弹出?
【发布时间】:2013-04-28 03:02:05
【问题描述】:

在多显示器系统上使用 javascript window.open() 时,您如何控制哪个显示器或弹出窗口在显示空间的哪个位置打开?对我来说,这似乎是失控的,而且它的行为是随机的。

【问题讨论】:

标签: javascript popup window window.open multiple-monitors


【解决方案1】:

由于安全原因,基于 javascript 的解决方案不起作用。

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

背景:我们遇到了相关的困难。在 windows 中打开多个文档的内部 webapp,需要放置在其他监视器中。 出于安全原因,javascript 不支持这一点,并且只有本机扩展才能正确使用选项卡/窗口对象。

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

在您的情况下,您可以轻松地为每个监视器定义一条规则,它会出现在哪里以及如何出现。您可以在 chrome 扩展的选项页面中执行此操作。 (快捷方式可以,安装后直接去using

Chrome 扩展名为“MultiWindow Positioner”,完全免费。您可以在 chrome 商店购买它here

你在项目chrome-multiwindow-positioner的github中找到的实际源码

免责声明:我是开源 (MIT) github 项目的维护者。如果有任何有趣的想法,或者 cmets 随时分享他们here

2020 年 9 月 21 日更新 离开那家公司后,我不再是开源项目的维护者。也就是说,我不理解反对意见,浏览器不提供 window.API 让您清楚地理解多个监视器,因为它明显的安全限制/违规。这就是浏览器插件扩展提供帮助的地方,因为它们不是一个网页,它们可以访问额外的 API,这些 API 可以准确地查找/列出监视器和窗口。它们遵循不同的安全上下文,因此具有额外的权力。并不是所有的浏览器都提供了用于多监视器支持的 require extension.API。 Mozilla Firefox 大多没有。 Chrome 和最新的 MS Edge 是的。 经过这么多年的经验,我仍然 100% 没有纯 javascript 解决方案,唯一的方法是涉及浏览器插件/扩展的解决方案。

【讨论】:

  • “为什么不使用 chrome 扩展”...好吧,因为要求我们网站的随机访问者安装扩展只是为了定位弹出窗口听起来并不理想。
  • 是的,从这个意义上说,那是行不通的。它实际上是一个灰色地带。基于浏览器的应用程序需要越来越多的功能,这些功能想要进入浏览器选项卡的范围,而浏览器必须保护用户免受安全问题的影响。这是一个矛盾。
  • 而且,从个人经验来看,我可以提供反馈,在我工作的公司中,很多人如果没有这个扩展就活不下去了。它确实让基于浏览器的应用程序的高级用户以及开发人员的生活变得更加轻松。我收到了将其移植到其他浏览器的请求,但由于 FF 或 IE 没有所需的接口,这是不可能的:(
【解决方案2】:

这里有一个解决方案:

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 到 openWindow

【讨论】:

    【解决方案3】:

    “window.open 双屏”搜索结果显示了这个花哨的金块:Dual Monitors and 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.open 打开一个 父窗口所在的监视器上的窗口。

    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/browsers 中没有内置功能可以理解多个显示器,只是双屏桌面只是一个放大的单个笛卡尔平面而不是两个离散平面.

    更新

    链接已失效。使用this waybackmachine link

    【讨论】:

    • 您的代码是 returnign 'window.leftWindowBoundry 不是函数'。我正在尝试使用 chrome 63.0.3239.132。
    • 在他发布的回退链接阅读文档。
    • 这一切都很花哨,我很喜欢。但为什么不直接使用 window.screenX?
    【解决方案4】:

    以上解决方案均无法正常工作。就确切的中心而言,

    我试过了,它在 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));
    

    但是,如果第二个监视器浏览器在第一和第二个中被查看一半,这也会有问题。

    【讨论】:

      【解决方案5】:

      功能:

      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}); 
      

      它也适用于最小化的窗口

      【讨论】:

      • 这很棒!虽然我想要左上角,所以我只是夸大了第一个宽度和高度的划分,然后将第二个(w和h)除以1。从来不明白'google.com'的功能在使用中是什么,但发现它可以是任何东西,只要它是任何东西。
      • @drymoon 你知道为什么这会在同一个窗口中打开每个链接而不是一个新的吗?真烦人/:
      • 似乎只适用于具有相同核心 URL 的链接。
      • @drymoon window.open()的第二个参数叫做windowName。这不会用作窗口的显示标题,而是像 target 属性一样工作,例如。 元素。 (见developer.mozilla.org/en-US/docs/Web/API/Window/open)如果设置为_blank(或调用PopupCenter,第二个参数为'_blank',总是会打开一个新窗口。
      • @dryymoon 对我来说这总是在同一个屏幕上打开窗口。如何在其他屏幕上打开它?
      【解决方案6】:
      /**
       * 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);
      },
      

      【讨论】:

        【解决方案7】:

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

        假设显示器宽度为 1360

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

        用于监视器 2 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;
        
        }
        

        【讨论】:

        • 我正在尝试使用此技术解决将弹出窗口放置在另一台显示器上的问题。它在 Firefox 和 IE 中按预期工作。但在 chrome 中,它不起作用。它在窗口的右边缘放置弹出窗口。有什么想法吗?
        • @RumitParakhiya 你有什么解决办法吗?我遇到了同样的问题,它在 firefox 上工作,但在 chrome 上没有
        • @Heroic:不,没有为 Chrome 找到任何解决方案。答案中提到的解决方案适用于 FF,但出于安全考虑,Chrome 不允许以这种方式放置弹出窗口。我当时通过一个官方的 Chrome 线程来确认这一点。网址目前不方便。
        • 监视器2的screenX不会是1361吗?
        猜你喜欢
        • 1970-01-01
        • 2011-11-06
        • 1970-01-01
        • 1970-01-01
        • 2014-03-11
        • 1970-01-01
        • 2022-07-31
        • 1970-01-01
        相关资源
        最近更新 更多