Centrer une fenêtre contextuelle à l'écran?


281

Comment centrer une fenêtre popup ouverte via la window.openfonction javascript au centre de la variable d'écran sur la résolution d'écran actuellement sélectionnée?

Réponses:


459

FONCTION MONITEUR UNIQUE / DOUBLE (crédit à http://www.xtf.dk - merci!)

MISE À JOUR: Cela fonctionnera également sur les fenêtres qui ne sont pas maximisées à la largeur et à la hauteur de l'écran maintenant grâce à @Frost!

Si vous êtes sur un double moniteur, la fenêtre sera centrée horizontalement, mais pas verticalement ... utilisez cette fonction pour en tenir compte.

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

Exemple d'utilisation:

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

LE CRÉDIT VA À: http://www.xtf.dk/2011/08/center-new-popup-window-even-on.html (je voulais simplement créer un lien vers cette page, mais juste au cas où ce site Web descendrait le le code est ici sur SO, cheers!)


7
Après quelques jeux, cela ne fonctionne pas aussi bien que je le pensais. La réponse plus simple et exceptée fonctionne beaucoup mieux. Cela ne fonctionne que si la page de lancement est maximisée.
Bart

8
Merci pour le crédit, j'ai fait mon exemple de travail sur les fenêtres réduites maintenant: xtf.dk/2011/08/center-new-popup-window-even-on.html
Frost

10
Utilise des variables globales (largeur / hauteur), aïe!
Ruben Stolk

13
Question d'origine publiée en 2010, solution d'origine publiée en 2010. Mon commentaire sur la solution d'origine de ne pas travailler sur le double moniteur publié en 2013, ma réponse pour le double moniteur publié en 2013. Votre commentaire sur le triple moniteur en 2015. Vous devez maintenant répondre pour une solution triple moniteur en 2015. A ce rythme, nous aurons une réponse pour 5 moniteurs en 2020, 6 moniteurs en 2025, 7 moniteurs en 2030 ... continuons ce cycle!
Tony M

2
@TonyM J'ai mis à jour la réponse. Oui, le cycle doit continuer!
Zo a

329

essayez-le comme ceci:

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
Cette fonction ne fonctionne pas sur une configuration à deux écrans. J'ai posté une solution de moniteur simple et double ci-dessous.
Tony M

1
Je voudrais confirmer ceci: var left = (screen.width / 2) - (w / 2); var top = (screen.height / 2) - (h / 2); N'est-ce pas qu'il retournera à gauche = 0 et en haut = 0 ??? En supposant que w est égal à screen.width et h est égal à screen.height ... Ai-je raison ou tort ici?
mutanique

1
@mutanic w / h fait référence à la taille de la fenêtre contextuelle, pas à l'écran.
Mahn

2
Ne se centre pas sur mon deuxième moniteur (qui est HAUT par rapport au principal). La réponse pour le double écran échoue également.
vsync

2
Cela ne fonctionnera pas si vous souhaitez centrer la fenêtre au milieu du navigateur, plutôt qu'au milieu de l'écran (si par exemple, l'utilisateur a redimensionné son navigateur à la moitié de la taille). Pour centrer dans le navigateur, remplacez screen.width & screen.height par window.innerWidth & window.innerHeight
Jonathon Blok

71

En raison de la complexité de la détermination du centre de l'écran actuel dans une configuration à plusieurs moniteurs, une option plus simple consiste à centrer la fenêtre contextuelle sur la fenêtre parent. Passez simplement la fenêtre parent comme autre paramètre:

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

La mise en oeuvre:

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

Cela semble être la technique utilisée par Facebook pour le popup sur un bouton de partage.
Tim Tisdall

3
Cela a parfaitement fonctionné pour moi sur double écran. Même lors du déplacement ou du redimensionnement de la fenêtre, il indique au centre de la fenêtre à partir de laquelle il est ouvert. Ce devrait être la réponse acceptée. Merci.
Oli B

2
Je suis d'accord avec @OliB - cela fonctionne parfaitement et a résolu un problème de développement récent que nous avions! Devrait être la réponse acceptée pour 2019.
MrLewk

Apporté une modification pour étendre les capacités de cette fonction ici . Il comprend une option pour définir la largeur et la hauteur en pourcentage ou en rapport. Vous pouvez également modifier les options avec un objet (plus facile à gérer qu'une chaîne)
SwiftNinjaPro


15

Si vous souhaitez le centrer sur le cadre dans lequel vous vous trouvez actuellement, je recommanderais cette fonction:

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

Similaire à la réponse de Crazy Tim, mais n'utilise pas window.top. De cette façon, cela fonctionnera même si la fenêtre est intégrée dans une iframe d'un autre domaine.


13

Cela fonctionne très bien dans Firefox.
Remplacez simplement la variable supérieure par un autre nom et réessayez

        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
C'est totalement inutile Number(...).
gustavohenke

6

Ma recommandation est d'utiliser l'emplacement supérieur à 33% ou 25% de l'espace restant,
et non à 50% comme d'autres exemples publiés ici,
principalement en raison de l'en -tête de la fenêtre ,
qui a l'air meilleur et plus confortable pour l'utilisateur,

code complet:

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



consultez cette ligne:
var top = (screen.height - h) / 4; // pour 25% - diviser par 4 | pour 33% - divisez par 3


6

Facebook utilise l'algorithme suivant pour positionner sa fenêtre contextuelle de connexion:

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

Vous pouvez utiliser css pour le faire, donnez simplement les propriétés suivantes à l'élément à placer au centre de la 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

Voici une version alternative de la solution susmentionnée ...

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

Ma version avec ES6 JavaScript.
Fonctionne bien sur Chrome et Chrome avec une configuration à double écran.

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

Exemple

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

2

(cela a été publié en 2020)

Une extension de la réponse de CrazyTim

Vous pouvez également définir la largeur sur un pourcentage (ou un ratio) pour une taille dynamique. La taille absolue est toujours acceptée.

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

usage:

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

Remarque: vous devez utiliser Math.roundpour obtenir l'entier exact de largeur et de hauteur.


0

Basé sur Facebook, mais utilise une requête multimédia plutôt que l'expression rationnelle de l'agent utilisateur pour calculer s'il y a suffisamment de place (avec un peu d'espace) pour le popup, sinon passe en plein écran. Les popups sur le mobile s'ouvrent quand même comme de nouveaux onglets.

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

Cette solution hybride a fonctionné pour moi, à la fois sur la configuration simple et double écran

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

J'ai eu un problème avec le centrage d'une fenêtre contextuelle dans le moniteur externe et window.screenX et window.screenY étaient des valeurs négatives (-1920, -1200) respectivement. J'ai essayé toutes les solutions suggérées ci-dessus et elles ont bien fonctionné dans les moniteurs primaires. Je voulais partir

  • Marge de 200 px pour gauche et droite
  • Marge de 150 px pour le haut et le bas

Voici ce qui a fonctionné pour moi:

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

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.