Skip to content

Instantly share code, notes, and snippets.

@csandman
Last active November 26, 2019 14:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save csandman/51ad472b4c2cce5b87049766c0d983e5 to your computer and use it in GitHub Desktop.
Save csandman/51ad472b4c2cce5b87049766c0d983e5 to your computer and use it in GitHub Desktop.
Center a popup window with 1 or 2 monitors

A somewhat niche problem is opening a centered popup window when you have multiple monitors. One you case you might encounter for this is opening a Twitter Web Intent window, which creates a tweet for a user to post. Here is their recomended code for opening a Web Intent popup:

(function() {
  if (window.__twitterIntentHandler) return;
  var intentRegex = /twitter\.com\/intent\/(\w+)/,
      windowOptions = 'scrollbars=yes,resizable=yes,toolbar=no,location=yes',
      width = 550,
      height = 420,
      winHeight = screen.height,
      winWidth = screen.width;

  function handleIntent(e) {
    e = e || window.event;
    var target = e.target || e.srcElement,
        m, left, top;

    while (target && target.nodeName.toLowerCase() !== 'a') {
      target = target.parentNode;
    }

    if (target && target.nodeName.toLowerCase() === 'a' && target.href) {
      m = target.href.match(intentRegex);
      if (m) {
        left = Math.round((winWidth / 2) - (width / 2));
        top = 0;

        if (winHeight > height) {
          top = Math.round((winHeight / 2) - (height / 2));
        }

        window.open(target.href, 'intent', `${windowOptions},width=${width},height=${height},left=${left} + ',top=' + top);
        e.returnValue = false;
        e.preventDefault && e.preventDefault();
      }
    }
  }

  if (document.addEventListener) {
    document.addEventListener('click', handleIntent, false);
  } else if (document.attachEvent) {
    document.attachEvent('onclick', handleIntent);
  }
  window.__twitterIntentHandler = true;
}());

And this can be simplified down to

function openIntentPopup(link) {
  const windowOptions = 'scrollbars=yes,resizable=yes,toolbar=no,location=yes';
  const width = 550;
  const height = 420;
  const winHeight = screen.height;
  const winWidth = screen.width;
  const left = Math.round((winWidth / 2) - (width / 2));
  let top = 0;

  if (winHeight > height) {
    top = Math.round((winHeight / 2) - (height / 2));
  }

  window.open(link, 'intent', windowOptions + ',width=' + width +
    ',height=' + height + ',left=' + left + ',top=' + top);
}

This works fine for the most part, however, as soon as a user has 2 monitors, this will break. After browsing a little bit, I found this stackoverflow post that provided an elegant solution to this problem:

function PopupCenter(url, title, w, h) {
  // Fixes dual-screen position                         Most browsers      Firefox
  var dualScreenLeft = window.screenLeft != undefined ? window.screenLeft : window.screenX;
  var dualScreenTop = window.screenTop != undefined ? window.screenTop : window.screenY;

  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 systemZoom = width / window.screen.availWidth;
  var left = (width - w) / 2 / systemZoom + dualScreenLeft
  var top = (height - h) / 2 / systemZoom + dualScreenTop
  var newWindow = window.open(url, title, 'scrollbars=yes, width=' + w / systemZoom + ', height=' + h / systemZoom + ', top=' + top + ', left=' + left);

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

}

However, eslint got mad at me for multiple reasons when I used that solution, so here is my modified version of it which should leave your editor a little happier:

function popupInCenter(url, title, w, h, extraOpts) {
  // Fixes dual-screen position
  const dualScreenLeft =
    window.screenLeft !== undefined ? window.screenLeft : window.screenX; // Most Browsers : Firefox
  const dualScreenTop =
    window.screenTop !== undefined ? window.screenTop : window.screenY;

  let width;
  if (window.innerWidth) {
    width = window.innerWidth;
  } else if (document.documentElement.clientWidth) {
    width = document.documentElement.clientWidth;
  } else {
    width = window.screen.width;
  }

  let height;
  if (window.innerHeight) {
    height = window.innerHeight;
  } else if (document.documentElement.clientHeight) {
    height = document.documentElement.clientHeight;
  } else {
    height = window.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}, ${extraOpts}`
  );

  // Puts focus on the newWindow
  if (window.focus) newWindow.focus();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment