【问题标题】:How do I get JavaScript to open a popup window on the current monitor如何让 JavaScript 在当前监视器上打开一个弹出窗口
【发布时间】:2008-09-11 21:06:21
【问题描述】:

场景:

  1. 用户有两台显示器。
  2. 他们的浏览器已在辅助监视器上打开。
  3. 他们单击浏览器中的链接,该链接调用具有特定顶部和左侧窗口偏移量的 window.open()。
  4. 弹出窗口始终在其主监视器上打开。

在 JavaScript 中有什么方法可以让弹出窗口在与初始浏览器窗口(打开器)相同的监视器上打开?

【问题讨论】:

  • 这些“解决方案”中没有一个对我有用。你有什么办法吗。
  • @oma 我提供了一个适合我的解决方案,但在这篇文章中得到了回答:stackoverflow.com/questions/6911138/…
  • 你应该把它贴在这里。另一个是 dup,这个线程有更多相关的上下文。
  • 是的,我在另一个帖子上发布我的答案后才看到这个问题 - 让我把我的答案移过来

标签: javascript multiple-monitors


【解决方案1】:

您不能指定监视器,但可以将弹出窗口的位置指定为相对于单击导致窗口弹出的位置。

使用 getMouseXY() 函数获取值以作为 left 和 top args 传递给 window.open() 方法。 (left 和 top args 仅适用于 V3 及更高版本的浏览器)。

window.open 文档: 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;
}

【讨论】:

    【解决方案2】:

    这是我从 Facebook oauth API 无耻地逆向工程的东西。在 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));
    

    【讨论】:

    • 这条线有什么意义? var h = (a &lt; 0) ? window.screen.width + a : a; 那条线没有为我正确定位屏幕。
    • 在 OS X 上,这适用于 Firefox 中的所有监视器排列。不适用于 Chrome 中的显示器上下排列(将正确水平放置,但不会垂直移动到主显示器之外)。不适用于 Safari 中的并排排列(将正确垂直定位,但不会水平移动超出主显示器)。对于 chrome 和 safari,我认为没有其他事情要做,似乎是浏览器限制/错误。
    • 这对我来说在尝试定位 facebook 共享对话框时非常有效(我敢打赌,很多查找这个问题的人都是出于同样的原因这样做)。
    • @plainjimbo 我认为这可能是一些浏览器在 2 个屏幕的情况下返回 screenX 作为另一个屏幕的 -ve。不明白为什么顶部除以 2.5。
    【解决方案3】:
    // 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))
    }
    

    像下面这样调用它,它将在当前窗口的顶部打开

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

    或者稍微偏移一下

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

    关键是 window.screenX/screenLeft 为您提供与整个桌面相关的位置,而不仅仅是显示器。

    window.screen.left 是为您提供所需信息的理想人选。问题是它是在页面加载时设置的,用户可以将窗口移动到另一个监视器。

    更多研究

    这个问题的最终解决方案(不仅仅是从当前窗口位置偏移)需要知道窗口所在屏幕的尺寸。由于屏幕对象不会随着用户移动窗口而更新,我们需要制作我们自己的检测当前屏幕分辨率的方法。这是我想出的

    /**
     * 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();
    };
    

    因此,如果您想始终在窗口所在的任何监视器的左上角打开窗口,您可以使用以下命令:

    function openAtTopLeftOfSameMonitor(url, winName) {
      getScreenProps(function(scr){
        window.open(url, winName, 'top=0,left=' + scr.left);
      })
    }
    

    【讨论】:

    • 在 FF 中工作。好像chrome不太关心left和top参数。
    【解决方案4】:

    在当前显示器上打开居中的窗口,也适用于 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();
        }
    }
    

    【讨论】:

      【解决方案5】:

      如果你知道每台显示器的分辨率,你就可以估计出来。 对于公共网站来说,这是一个坏主意,但如果您知道(出于某种奇怪的原因)这种情况将始终适用,则可能会有用。

      相对于鼠标(如上所述)或原始浏览器窗口的相对位置也可能很有用,尽管您必须假设用户使用最大化的浏览器(这不一定是真的)。​​

      【讨论】:

        【解决方案6】:

        我最近遇到了这个问题,终于找到了一种方法来将弹出窗口定位在触发它的屏幕上。在我的 github 页面上查看我的解决方案:https://github.com/svignara/windowPopUp

        诀窍在于使用window.screen 对象,该对象返回availWidthavailHeightavailLeftavailTop 值(以及widthheight)。有关对象中变量的完整列表以及这些变量所代表的含义,请查看https://developer.mozilla.org/en-US/docs/DOM/window.screen

        基本上,只要单击弹出窗口的触发器,我的解决方案就会找到 window.screen 的值。这样我就可以确定从哪个监视器屏幕上单击它。 availLeft 值负责其余部分。方法如下:

        基本上,如果左侧的第一个可用像素 (availLeft) 为负数,则说明“主”监视器左侧有一个监视器。同样,如果左起第一个可用像素大于 0,则意味着以下两种情况之一:

        1. 监视器位于“主”监视器的右侧,或者
        2. 屏幕左侧有一些“垃圾”(可能是应用程序 Dock 或 Windows 开始菜单)

        在任何一种情况下,您都希望弹出窗口的偏移量从左侧可用像素之后开始。

        offsetLeft = availableLeft + ( (availableWidth - modalWidth) / 2 )
        

        【讨论】:

          【解决方案7】:

          只有 user11153 的版本适用于 Chrome 和双屏。这是它的 TypeScript 版本。

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

          【讨论】:

            【解决方案8】:

            只要您知道落在特定显示器上的 x 和 y 位置,您就可以做到:

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

            【讨论】:

            • OP 应该如何知道 x 和 y 位置?你不能假设总是有两个显示器,或者它们的分辨率......这没有帮助。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2018-08-11
            • 1970-01-01
            • 1970-01-01
            • 2023-02-26
            • 1970-01-01
            • 2011-02-16
            • 2012-12-12
            相关资源
            最近更新 更多