Centra una finestra popup sullo schermo?


281

Come possiamo centrare una finestra popup aperta tramite la window.openfunzione javascript al centro della variabile dello schermo alla risoluzione dello schermo attualmente selezionata?

Risposte:


459

FUNZIONE MONITOR SINGOLA / DOPPIA (merito a http://www.xtf.dk - grazie!)

AGGIORNAMENTO: Funzionerà anche su finestre che non hanno raggiunto il limite massimo di larghezza e altezza dello schermo grazie a @Frost!

Se sei su doppio monitor, la finestra sarà centrata in orizzontale, ma non in verticale ... usa questa funzione per tenerne conto.

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

Esempio di utilizzo:

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

IL CREDITO VA A: http://www.xtf.dk/2011/08/center-new-popup-window-even-on.html (volevo solo collegarmi a questa pagina ma nel caso in cui questo sito web non il codice è qui su SO, evviva!)


7
Dopo aver giocato un po ', questo non funziona come pensavo. La risposta più semplice ed esclusa funziona molto meglio. Funziona solo se la pagina di avvio è ingrandita.
Bart,

8
Grazie per il merito, ho fatto funzionare il mio esempio su Windows ridotto a icona ora: xtf.dk/2011/08/center-new-popup-window-even-on.html
Frost

10
Utilizza variabili globali (larghezza / altezza), ahi!
Ruben Stolk,

13
Domanda originale pubblicata nel 2010, soluzione originale pubblicata nel 2010. Il mio commento sulla soluzione originale di non funzionare su doppio monitor pubblicato nel 2013, la mia risposta per doppio monitor pubblicata nel 2013. Il tuo commento su triplo monitor nel 2015. Ora devi rispondere per una soluzione a tre monitor nel 2015. A questo ritmo, avremo una risposta per 5 monitor nel 2020, 6 monitor nel 2025, 7 monitor nel 2030 ... continuiamo questo ciclo!
Tony M,

2
@TonyM Ho aggiornato la risposta. Sì, il ciclo deve continuare!
Zo ha il

329

provalo così:

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

17
Questa funzione non funziona su una configurazione a doppio monitor. Di seguito ho pubblicato una soluzione per monitor singolo e doppio.
Tony M

1
Vorrei confermare questo: var left = (screen.width / 2) - (w / 2); var top = (screen.height / 2) - (h / 2); Non restituirà left = 0 e top = 0 ??? Supponendo che w sia uguale a screen.width e h sia uguale a screen.height ... Ho ragione o torto qui?
mutanico

1
@mutanic w / h si riferisce alle dimensioni del popup, non allo schermo.
Mahn,

2
Non è centrato sul mio secondo monitor (che è SU da quello principale). Anche la risposta per il doppio schermo non riesce.
vsync,

2
Questo non funzionerà se si desidera centrare la finestra al centro del browser, piuttosto che al centro dello schermo (se, ad esempio, l'utente ha il suo browser ridimensionato a metà dimensione). Per centrare all'interno del browser sostituire screen.width & screen.height con window.innerWidth & window.innerHeight
Jonathon Blok,

71

A causa della complessità di determinare il centro dello schermo corrente in un'impostazione multi-monitor, un'opzione più semplice è centrare il pop-up sulla finestra principale. Passa semplicemente la finestra principale come un altro parametro:

function popupWindow(url, title, 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, 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}`);
}

Implementazione:

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

Questa sembra essere la tecnica utilizzata da Facebook per il popup su un pulsante di condivisione.
Tim Tisdall,

3
Questo ha funzionato perfettamente per me sul doppio schermo. Anche quando si sposta o si ridimensiona la finestra, dice centrale alla finestra da cui è aperta. Questa dovrebbe essere la risposta accettata. Grazie.
Oli B,

2
Sono d'accordo con @OliB - questo funziona perfettamente e ha risolto un recente problema di sviluppo che abbiamo avuto! Dovrebbe essere la risposta accettata per il 2019.
MrLewk,

Apportata una modifica per estendere le capacità di questa funzione qui . Include l'opzione per impostare larghezza e altezza su percentuale o rapporto. Puoi anche cambiare le opzioni con un oggetto (più facile da gestire di una stringa)
SwiftNinjaPro


15

Se vuoi centrarlo sul fotogramma in cui ti trovi attualmente, consiglierei questa funzione:

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

Simile alla risposta di Crazy Tim, ma non usa window.top. In questo modo, funzionerà anche se la finestra è incorporata in un iframe di un dominio diverso.


13

Funziona molto bene in Firefox.
Basta cambiare la variabile superiore con qualsiasi altro nome e riprovare

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

6
Non è assolutamente necessario farlo Number(...).
gustavohenke,

6

La mia raccomandazione è di utilizzare la posizione superiore del 33% o del 25% dallo spazio rimanente
e non del 50% come altri esempi pubblicati qui,
principalmente a causa dell'intestazione della finestra ,
che ha un aspetto migliore e un maggiore comfort per l'utente,

codice completo:

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



controlla questa riga:
var top = (screen.height - h) / 4; // per il 25% - dividi per 4 | per il 33% - dividi per 3


6

Facebook utilizza il seguente algoritmo per posizionare la finestra popup di accesso:

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

4

Puoi usare css per farlo, basta dare le seguenti proprietà all'elemento da posizionare al centro del popup

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

}

3

Ecco una versione alternativa della suddetta soluzione ...

function openPopupCenter(url, title, w, h) {
  // Fixes dual-screen position
  // Most browsers use window.screenLeft
  // Firefox uses screen.left
  var dualScreenLeft = getFirstNumber(window.screenLeft, screen.left),
    dualScreenTop = getFirstNumber(window.screenTop, screen.top),
    width = getFirstNumber(window.innerWidth, document.documentElement.clientWidth, screen.width),
    height = getFirstNumber(window.innerHeight, document.documentElement.clientHeight, screen.height),
    left = ((width / 2) - (w / 2)) + dualScreenLeft,
    top = ((height / 2) - (h / 2)) + dualScreenTop,
    newWindow = window.open(url, title, getSpecs());

  // Puts focus on the newWindow
  if (window.focus) {
    newWindow.focus();
  }

  return newWindow;

  function getSpecs() {
    return 'scrollbars=yes, width=' + w + ', height=' + h + ', top=' + top + ', left=' + left;
  }

  function getFirstNumber() {
    for(var i = 0, len = arguments.length; i < len; i++) {
      var value = arguments[i];

      if (typeof value === 'number') {
        return value;
      }
    }
  }
}

3

La mia versione con ES6 JavaScript.
Funziona bene su Chrome e Chromium con configurazione a doppio schermo.

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

Esempio

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

2

(questo è stato pubblicato nel 2020)

Un'estensione alla risposta di CrazyTim

Puoi anche impostare la larghezza su una percentuale (o un rapporto) per una dimensione dinamica. La dimensione assoluta è ancora accettata.

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

utilizzo:

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

1
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>

Nota: devi usare Math.roundper ottenere l'esatto numero intero di larghezza e altezza.


0

Basato su Facebook ma utilizza una query multimediale anziché regex dell'agente utente per calcolare se c'è spazio sufficiente (con un po 'di spazio) per il popup, altrimenti passa a schermo intero. I popup di Tbh sul cellulare si aprono comunque come nuove schede.

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

0

Questa soluzione ibrida ha funzionato per me, sia in configurazione a schermo singolo che doppio

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

0

Ho avuto un problema con il centraggio di una finestra popup nel monitor esterno e window.screenX e window.screenY erano valori negativi (-1920, -1200) rispettivamente. Ho provato tutto quanto sopra delle soluzioni suggerite e hanno funzionato bene nei monitor primari. Volevo andarmene

  • Margine di 200 px per sinistra e destra
  • Margine di 150 px per la parte superiore e inferiore

Ecco cosa ha funzionato per me:

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

-4

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.