【问题标题】:Center a popup window on screen?在屏幕上居中弹出窗口?
【发布时间】:2011-05-03 08:58:30
【问题描述】:

我们如何将通过 javascript window.open 函数打开的弹出窗口在屏幕变量的中心以当前选择的屏幕分辨率居中?

【问题讨论】:

    标签: javascript


    【解决方案1】:

    除非浏览器占据全屏,否则接受的解决方案不起作用,

    这似乎总是有效

      const popupCenterScreen = (url, title, w, h, focus) => {
        const top = (screen.height - h) / 4, left = (screen.width - w) / 2;
        const popup = window.open(url, title, `scrollbars=yes,width=${w},height=${h},top=${top},left=${left}`);
        if (focus === true && window.focus) popup.focus();
        return popup;
      }
    

    实施:

    some.function.call({data: ''})
        .then(result =>
         popupCenterScreen(
             result.data.url,
             result.data.title, 
             result.data.width, 
             result.data.height, 
             true));
    

    【讨论】:

      【解决方案2】:

      这是上述解决方案的替代版本...

      const openPopupCenter = (url, title, w, h) => {
        const getSpecs = (w, h, top, left) => {
          return `scrollbars=yes, width=${w}, height=${h}, top=${top}, left=${left}`;
        };
      
        const getFirstNumber = (potentialNumbers) => {
          for(let i = 0; i < potentialNumbers.length; i++) {
            const value = potentialNumbers[i];
      
            if (typeof value === 'number') {
              return value;
            }
          }
        };
      
        // Fixes dual-screen position
        // Most browsers use window.screenLeft
        // Firefox uses screen.left
        const dualScreenLeft = getFirstNumber([window.screenLeft, screen.left]);
        const dualScreenTop = getFirstNumber([window.screenTop, screen.top]);
        const width = getFirstNumber([window.innerWidth, document.documentElement.clientWidth, screen.width]);
        const height = getFirstNumber([window.innerHeight, document.documentElement.clientHeight, screen.height]);
        const left = ((width / 2) - (w / 2)) + dualScreenLeft;
        const top = ((height / 2) - (h / 2)) + dualScreenTop;
        const newWindow = window.open(url, title, getSpecs(w, h, top, left));
      
        // Puts focus on the newWindow
        if (window.focus) {
          newWindow.focus();
        }
      
        return newWindow;
      }
      

      【讨论】:

        【解决方案3】:

        由于在多显示器设置中确定当前屏幕中心的复杂性,一个更简单的选择是将弹出窗口置于父窗口的中心。只需将父窗口作为另一个参数传递:

        function popupWindow(url, windowName, win, w, h) {
            const y = win.top.outerHeight / 2 + win.top.screenY - ( h / 2);
            const x = win.top.outerWidth / 2 + win.top.screenX - ( w / 2);
            return win.open(url, windowName, `toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=no, copyhistory=no, width=${w}, height=${h}, top=${y}, left=${x}`);
        }
        

        实施:

        popupWindow('google.com', 'test', window, 200, 100);
        

        【讨论】:

        • 这似乎是 Facebook 用于在分享按钮上弹出窗口的技术。
        • 这对我来说在双屏上非常有效。即使在移动或调整窗口大小时,它也会显示打开它的窗口的中心。这应该是公认的答案。谢谢。
        • 我同意@OliB 的观点——这非常有效,并且解决了我们最近遇到的一个开发问题!应该是 2019 年公认的答案。
        • 进行了修改以扩展此函数here 的功能。它包括将宽度和高度设置为百分比或比率的选项。您还可以使用对象更改选项(比字符串更易于管理)
        • 不错且简单的解决方案。就我而言,使用“outerHeight / 2.7”而不是“outerHeight / 2”看起来更好。另一件事:参数名称“title”具有误导性。它是窗口的名称,所以 winName 左右更好,更切中要害。
        【解决方案4】:

        这将根据您的屏幕尺寸解决

        <html>
        <body>
        <button onclick="openfunc()">Click here to open window at center</button>
        <script>
        function openfunc() {
        windowWidth = 800;
        windowHeight = 720;
         var left = (screen.width - windowWidth) / 2;
                    var top = (screen.height - windowHeight) / 4;
                    var myWindow = window.open("https://www.google.com",'_blank','width=' + windowWidth + ', height=' + windowHeight + ', top=' + top + ', left=' + left);
        }
        </script>
        </body>
        </html>
        

        【讨论】:

          【解决方案5】:

          我在外接显示器中居中弹出窗口时遇到问题,window.screenXwindow.screenY 分别为负值(-1920、-1200)。我已经尝试了上述所有建议的解决方案,它们在主显示器中运行良好。我想离开

          • 200 px左右边距
          • 上下边距为 150 像素

          这对我有用:

           function createPopupWindow(url) {
              var height = screen.height;
              var width = screen.width;
              var left, top, win;
          
              if (width > 1050) {
                  width = width - 200;
              } else {
                  width = 850;
              }
          
              if (height > 850) {
                  height = height - 150;
              } else {
                  height = 700;
              }
          
              if (window.screenX < 0) {
                  left = (window.screenX - width) / 2;
              } else {
                  left = (screen.width - width) / 2;
              }
          
              if (window.screenY < 0) {
                  top = (window.screenY + height) / 4;
              } else {
                  top = (screen.height - height) / 4;
              }
          
              win=window.open( url,"myTarget", "width="+width+", height="+height+",left="+left+",top="+top+"menubar=no, status=no, location=no, resizable=yes, scrollbars=yes");
              if (win.focus) {
                  win.focus();
              }
          }
          

          【讨论】:

            【解决方案6】:

            (这是在 2020 年发布的)

            CrazyTim's answer 的扩展

            您还可以将宽度设置为动态尺寸的百分比(或比率)。 仍然接受绝对大小。

            function popupWindow(url, title, w='75%', h='16:9', opts){
                // sort options
                let options = [];
                if(typeof opts === 'object'){
                    Object.keys(opts).forEach(function(value, key){
                        if(value === true){value = 'yes';}else if(value === false){value = 'no';}
                        options.push(`${key}=${value}`);
                    });
                    if(options.length){options = ','+options.join(',');}
                    else{options = '';}
                }else if(Array.isArray(opts)){
                    options = ','+opts.join(',');
                }else if(typeof opts === 'string'){
                    options = ','+opts;
                }else{options = '';}
            
                // add most vars to local object (to shorten names)
                let size = {w: w, h: h};
                let win = {w: {i: window.top.innerWidth, o: window.top.outerWidth}, h: {i: window.top.innerHeight, o: window.top.outerHeight}, x: window.top.screenX || window.top.screenLeft, y: window.top.screenY || window.top.screenTop}
            
                // set window size if percent
                if(typeof size.w === 'string' && size.w.endsWith('%')){size.w = Number(size.w.replace(/%$/, ''))*win.w.o/100;}
                if(typeof size.h === 'string' && size.h.endsWith('%')){size.h = Number(size.h.replace(/%$/, ''))*win.h.o/100;}
            
                // set window size if ratio
                if(typeof size.w === 'string' && size.w.includes(':')){
                    size.w = size.w.split(':', 2);
                    if(win.w.o < win.h.o){
                        // if height is bigger than width, reverse ratio
                        size.w = Number(size.h)*Number(size.w[1])/Number(size.w[0]);
                    }else{size.w = Number(size.h)*Number(size.w[0])/Number(size.w[1]);}
                }
                if(typeof size.h === 'string' && size.h.includes(':')){
                    size.h = size.h.split(':', 2);
                    if(win.w.o < win.h.o){
                        // if height is bigger than width, reverse ratio
                        size.h = Number(size.w)*Number(size.h[0])/Number(size.h[1]);
                    }else{size.h = Number(size.w)*Number(size.h[1])/Number(size.h[0]);}
                }
            
                // force window size to type number
                if(typeof size.w === 'string'){size.w = Number(size.w);}
                if(typeof size.h === 'string'){size.h = Number(size.h);}
            
                // keep popup window within padding of window size
                if(size.w > win.w.i-50){size.w = win.w.i-50;}
                if(size.h > win.h.i-50){size.h = win.h.i-50;}
            
                // do math
                const x = win.w.o / 2 + win.x - (size.w / 2);
                const y = win.h.o / 2 + win.y - (size.h / 2);
                return window.open(url, title, `width=${size.w},height=${size.h},left=${x},top=${y}${options}`);
            }
            

            用法:

            // width and height are optional (defaults: width = '75%' height = '16:9')
            popupWindow('https://www.google.com', 'Title', '75%', '16:9', {/* options (optional) */});
            
            // options can be an object, array, or string
            
            // example: object (only in object, true/false get replaced with 'yes'/'no')
            const options = {scrollbars: false, resizable: true};
            
            // example: array
            const options = ['scrollbars=no', 'resizable=yes'];
            
            // example: string (same as window.open() string)
            const options = 'scrollbars=no,resizable=yes';
            

            【讨论】:

              【解决方案7】:

              单/双显示器功能(感谢http://www.xtf.dk - 谢谢!)

              更新:感谢@Frost,它现在也可以在没有达到屏幕宽度和高度的窗口上工作!

              如果您在双显示器上,窗口将水平居中,但不是垂直居中...使用此功能来解决这个问题。

              const popupCenter = ({url, title, w, h}) => {
                  // Fixes dual-screen position                             Most browsers      Firefox
                  const dualScreenLeft = window.screenLeft !==  undefined ? window.screenLeft : window.screenX;
                  const dualScreenTop = window.screenTop !==  undefined   ? window.screenTop  : window.screenY;
              
                  const width = window.innerWidth ? window.innerWidth : document.documentElement.clientWidth ? document.documentElement.clientWidth : screen.width;
                  const height = window.innerHeight ? window.innerHeight : document.documentElement.clientHeight ? document.documentElement.clientHeight : screen.height;
              
                  const systemZoom = width / window.screen.availWidth;
                  const left = (width - w) / 2 / systemZoom + dualScreenLeft
                  const top = (height - h) / 2 / systemZoom + dualScreenTop
                  const newWindow = window.open(url, title, 
                    `
                    scrollbars=yes,
                    width=${w / systemZoom}, 
                    height=${h / systemZoom}, 
                    top=${top}, 
                    left=${left}
                    `
                  )
              
                  if (window.focus) newWindow.focus();
              }
              

              用法示例:

              popupCenter({url: 'http://www.xtf.dk', title: 'xtf', w: 900, h: 500});  
              

              信用转至:http://www.xtf.dk/2011/08/center-new-popup-window-even-on.html(我只想链接到这个页面,但以防万一这个网站出现故障,代码就在这里,干杯!)

              【讨论】:

              • 玩了一段时间后,这并没有我想象的那么好。更简单的例外答案效果更好。这仅在启动页面最大化时才有效。
              • 感谢您的信任,我已经在最小化的窗口上制作了我的示例:xtf.dk/2011/08/center-new-popup-window-even-on.html
              • 使用全局变量(宽度/高度),哎哟!
              • 2010 年发布的原始问题,2010 年发布的原始解决方案。我对 2013 年发布的关于不能在双显示器上工作的原始解决方案的评论,我对双显示器的回答于 2013 年发布。您对三显示器的评论2015 年。您现在需要在 2015 年回答三显示器解决方案。按照这个速度,我们将在 2020 年回答 5 个显示器,2025 年 6 个显示器,2030 年 7 个显示器......让我们继续这个循环!跨度>
              • @TonyM 我已经更新了答案。是的,循环需要继续!
              【解决方案8】:

              .center{
                  left: 50%;
                  max-width: 350px;
                  padding: 15px;
                  text-align:center;
                  position: relative;
                  transform: translateX(-50%);
                  -moz-transform: translateX(-50%);
                  -webkit-transform: translateX(-50%);
                  -ms-transform: translateX(-50%);
                  -o-transform: translateX(-50%);   
              }

              【讨论】:

                【解决方案9】:

                我的 ES6 JavaScript 版本。
                在具有双屏设置的 Chrome 和 Chromium 上运行良好。

                function openCenteredWindow({url, width, height}) {
                    const pos = {
                        x: (screen.width / 2) - (width / 2),
                        y: (screen.height/2) - (height / 2)
                    };
                
                    const features = `width=${width} height=${height} left=${pos.x} top=${pos.y}`;
                
                    return window.open(url, '_blank', features);
                }
                

                例子

                openCenteredWindow({
                    url: 'https://stackoverflow.com/', 
                    width: 500, 
                    height: 600
                }).focus();
                

                【讨论】:

                  【解决方案10】:

                  这种混合解决方案对我来说适用于单屏和双屏设置

                  function popupCenter (url, title, w, h) {
                      // Fixes dual-screen position                              Most browsers      Firefox
                      const dualScreenLeft = window.screenLeft !== undefined ? window.screenLeft : window.screenX;
                      const dualScreenTop = window.screenTop !== undefined ? window.screenTop : window.screenY;
                      const left = (window.screen.width/2)-(w/2) + dualScreenLeft;
                      const top = (window.screen.height/2)-(h/2) + dualScreenTop;
                      return window.open(url, title, 'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=no, copyhistory=no, width='+w+', height='+h+', top='+top+', left='+left);
                  }
                  

                  【讨论】:

                    【解决方案11】:

                    基于 Facebook,但使用媒体查询而不是用户代理正则表达式来计算弹出窗口是否有足够的空间(有一些空间),否则会全屏显示。无论如何,移动设备上的 Tbh 弹出窗口都会作为新标签打开。

                    function popupCenter(url, title, w, h) {
                      const hasSpace = window.matchMedia(`(min-width: ${w + 20}px) and (min-height: ${h + 20}px)`).matches;
                      const isDef = v => typeof v !== 'undefined';
                      const screenX = isDef(window.screenX) ? window.screenX : window.screenLeft;
                      const screenY = isDef(window.screenY) ? window.screenY : window.screenTop;
                      const outerWidth = isDef(window.outerWidth) ? window.outerWidth : document.documentElement.clientWidth;
                      const outerHeight = isDef(window.outerHeight) ? window.outerHeight : document.documentElement.clientHeight - 22;
                      const targetWidth = hasSpace ? w : null;
                      const targetHeight = hasSpace ? h : null;
                      const V = screenX < 0 ? window.screen.width + screenX : screenX;
                      const left = parseInt(V + (outerWidth - targetWidth) / 2, 10);
                      const right = parseInt(screenY + (outerHeight - targetHeight) / 2.5, 10);
                      const features = [];
                    
                      if (targetWidth !== null) {
                        features.push(`width=${targetWidth}`);
                      }
                    
                      if (targetHeight !== null) {
                        features.push(`height=${targetHeight}`);
                      }
                    
                      features.push(`left=${left}`);
                      features.push(`top=${right}`);
                      features.push('scrollbars=1');
                    
                      const newWindow = window.open(url, title, features.join(','));
                    
                      if (window.focus) {
                        newWindow.focus();
                      }
                    
                      return newWindow;
                    }
                    

                    【讨论】:

                      【解决方案12】:

                      Facebook 使用以下算法来定位他们的登录弹出窗口:

                      function PopupCenter(url, title, w, h) {
                        var userAgent = navigator.userAgent,
                            mobile = function() {
                              return /\b(iPhone|iP[ao]d)/.test(userAgent) ||
                                /\b(iP[ao]d)/.test(userAgent) ||
                                /Android/i.test(userAgent) ||
                                /Mobile/i.test(userAgent);
                            },
                            screenX = typeof window.screenX != 'undefined' ? window.screenX : window.screenLeft,
                            screenY = typeof window.screenY != 'undefined' ? window.screenY : window.screenTop,
                            outerWidth = typeof window.outerWidth != 'undefined' ? window.outerWidth : document.documentElement.clientWidth,
                            outerHeight = typeof window.outerHeight != 'undefined' ? window.outerHeight : document.documentElement.clientHeight - 22,
                            targetWidth = mobile() ? null : w,
                            targetHeight = mobile() ? null : h,
                            V = screenX < 0 ? window.screen.width + screenX : screenX,
                            left = parseInt(V + (outerWidth - targetWidth) / 2, 10),
                            right = parseInt(screenY + (outerHeight - targetHeight) / 2.5, 10),
                            features = [];
                        if (targetWidth !== null) {
                          features.push('width=' + targetWidth);
                        }
                        if (targetHeight !== null) {
                          features.push('height=' + targetHeight);
                        }
                        features.push('left=' + left);
                        features.push('top=' + right);
                        features.push('scrollbars=1');
                      
                        var newWindow = window.open(url, title, features.join(','));
                      
                        if (window.focus) {
                          newWindow.focus();
                        }
                      
                        return newWindow;
                      }
                      

                      【讨论】:

                        【解决方案13】:

                        如果你想让它在你当前所在的框架上居中,我会推荐这个功能:

                        function popupwindow(url, title, w, h) {
                            var y = window.outerHeight / 2 + window.screenY - ( h / 2)
                            var x = window.outerWidth / 2 + window.screenX - ( w / 2)
                            return window.open(url, title, 'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=no, copyhistory=no, width=' + w + ', height=' + h + ', top=' + y + ', left=' + x);
                        } 
                        

                        类似于 Crazy Tim 的回答,但不使用 window.top。这样,即使窗口嵌入到来自不同域的 iframe 中,它也能正常工作。

                        【讨论】:

                          【解决方案14】:

                          来源:http://www.nigraphic.com/blog/java-script/how-open-new-window-popup-center-screen

                          function PopupCenter(pageURL, title,w,h) {
                            var left = (screen.width/2)-(w/2);
                            var top = (screen.height/2)-(h/2);
                            var targetWin = window.open (pageURL, title, 'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=no, copyhistory=no, width='+w+', height='+h+', top='+top+', left='+left);
                            return targetWin;
                          } 
                          

                          【讨论】:

                            【解决方案15】:

                            你可以使用css来做,只要给要放置在弹出窗口中心的元素以下属性

                            element{
                            
                            position:fixed;
                            left: 50%;
                            top: 50%;
                            -ms-transform: translate(-50%,-50%);
                            -moz-transform:translate(-50%,-50%);
                            -webkit-transform: translate(-50%,-50%);
                             transform: translate(-50%,-50%);
                            
                            }
                            

                            【讨论】:

                              【解决方案16】:
                              function fnPopUpWindow(pageId) {
                                   popupwindow("hellowWorld.php?id="+pageId, "printViewer", "500", "300");
                              }
                              
                              function popupwindow(url, title, w, h) {
                                  var left = Math.round((screen.width/2)-(w/2));
                                  var top = Math.round((screen.height/2)-(h/2));
                                  return window.open(url, title, 'toolbar=no, location=no, directories=no, status=no, '
                                          + 'menubar=no, scrollbars=yes, resizable=no, copyhistory=no, width=' + w 
                                          + ', height=' + h + ', top=' + top + ', left=' + left);
                              }
                              
                              <a href="javascript:void(0);" onclick="fnPopUpWindow('10');">Print Me</a>
                              

                              注意:您必须使用Math.round 来获取宽度和高度的精确整数。

                              【讨论】:

                                【解决方案17】:

                                我的建议是使用剩余空间的 33% 或 25% 的顶部位置,
                                而不是此处发布的其他示例的 50%,
                                主要是因为窗口标题
                                这对用户来说看起来更好,更舒适,

                                完整代码:

                                    <script language="javascript" type="text/javascript">
                                        function OpenPopupCenter(pageURL, title, w, h) {
                                            var left = (screen.width - w) / 2;
                                            var top = (screen.height - h) / 4;  // for 25% - devide by 4  |  for 33% - devide by 3
                                            var targetWin = window.open(pageURL, title, 'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=no, copyhistory=no, width=' + w + ', height=' + h + ', top=' + top + ', left=' + left);
                                        } 
                                    </script>
                                </head>
                                <body>
                                    <button onclick="OpenPopupCenter('http://www.google.com', 'TEST!?', 800, 600);">click on me</button>
                                </body>
                                </html>
                                



                                查看这一行:
                                var top = (screen.height - h) / 4; // 25% - 除以 4 | 33% - 除以 3

                                【讨论】:

                                  【解决方案18】:

                                  它在 Firefox 中运行良好。
                                  只需将顶部变量更改为任何其他名称,然后重试

                                          var w = 200;
                                          var h = 200;
                                          var left = Number((screen.width/2)-(w/2));
                                          var tops = Number((screen.height/2)-(h/2));
                                  
                                  window.open("templates/sales/index.php?go=new_sale", '', 'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=no, copyhistory=no, width='+w+', height='+h+', top='+tops+', left='+left);
                                  

                                  【讨论】:

                                  • 完全没必要做Number(...)
                                  【解决方案19】:

                                  像这样尝试:

                                  function popupwindow(url, title, w, h) {
                                    var left = (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=no, copyhistory=no, width='+w+', height='+h+', top='+top+', left='+left);
                                  } 
                                  

                                  【讨论】:

                                  • 此功能不适用于双显示器设置。我在下面发布了单显示器和双显示器解决方案。
                                  • 我想确认一下:var left = (screen.width/2)-(w/2); var top = (screen.height/2)-(h/2);不是会返回left=0和top=0吗???假设 w 等于 screen.width 并且 h 等于 screen.height ...我在这里是对还是错?
                                  • @mutanic w/h 指的是弹出窗口的大小,而不是屏幕。
                                  • 不以我的第二台显示器为中心(从主显示器开始)。双屏的回答也失败了。
                                  • 如果您想将窗口居中在浏览器的中间,而不是屏幕的中间(例如,如果用户将浏览器调整为一半大小),这将不起作用。要在浏览器中居中,将 screen.width 和 screen.height 替换为 window.innerWidth 和 window.innerHeight
                                  猜你喜欢
                                  • 1970-01-01
                                  • 2012-12-09
                                  • 2010-12-23
                                  • 1970-01-01
                                  • 1970-01-01
                                  • 1970-01-01
                                  • 2016-05-10
                                  • 1970-01-01
                                  • 1970-01-01
                                  相关资源
                                  最近更新 更多