Как мне получить JavaScript для открытия всплывающего окна на текущем мониторе - PullRequest
21 голосов
/ 12 сентября 2008

Сценарий:

  1. У пользователя два монитора.
  2. Их браузер открыт на дополнительном мониторе.
  3. Они нажимают на ссылку в браузере, которая вызывает window.open () с определенным смещением верхнего и левого окон.
  4. Всплывающее окно всегда открывается на их основном мониторе.

Есть ли в JavaScript способ заставить всплывающее окно открываться на том же мониторе, что и исходное окно браузера (средство открытия)?

Ответы [ 8 ]

22 голосов
/ 12 сентября 2008

Вы не можете указать монитор, но вы можете указать положение всплывающего окна относительно того, где щелчок вызвал всплывающее окно.

Используйте функцию getMouseXY (), чтобы получить значения для передачи в качестве аргументов left и top в метод window.open (). (левый и верхний аргументы работают только с браузерами 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;
}
18 голосов
/ 13 января 2011

Вот то, что я бесстыдно реверсировал в API oauth Facebook. Протестировано на основном и дополнительном мониторах в 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));
6 голосов
/ 24 января 2011
// 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);
  })
}
2 голосов
/ 24 октября 2014

Открыть центрированное окно на текущем мониторе, работая также с 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();
    }
}
0 голосов
/ 10 сентября 2018

Только версия 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;
}
0 голосов
/ 12 января 2013

Недавно я столкнулся с этой проблемой и, наконец, нашел способ разместить всплывающее окно на экране, с которого оно запускается. Посмотрите мое решение на моей странице github здесь: https://github.com/svignara/windowPopUp

Хитрость заключается в использовании объекта window.screen, который возвращает значения availWidth, availHeight, availLeft и availTop (а также width и height). Для полного списка переменных в объекте и того, что эти переменные представляют, смотрите https://developer.mozilla.org/en-US/docs/DOM/window.screen.

По сути, мое решение находит значения window.screen всякий раз, когда нажимается триггер для всплывающего окна. Таким образом, я точно знаю, с какого экрана монитора он щелкает. Значение availLeft позаботится обо всем остальном. Вот как это сделать:

Обычно, если первый доступный пиксель слева (availLeft) отрицательный, это говорит о том, что слева от «основного» монитора находится монитор. Аналогично, если первый доступный пиксель слева больше 0, это означает одну из двух вещей:

  1. Монитор находится справа от «основного» монитора, ИЛИ
  2. В левой части экрана есть «мусор» (возможно, панель приложения или меню запуска Windows)

В любом случае вы хотите, чтобы смещение всплывающего окна начиналось после доступного пикселя слева.

offsetLeft = availableLeft + ( (availableWidth - modalWidth) / 2 )
0 голосов
/ 15 июня 2009

Если вы знаете разрешение каждого монитора, вы можете оценить это. Плохая идея для общедоступного веб-сайта, но может быть полезной, если вы знаете (по какой-то странной причине), что этот сценарий всегда будет применяться.

Относительное положение по отношению к мыши (как сказано выше) или к исходному окну браузера также может быть полезным, хотя вы должны были бы предположить, что пользователь использует развернутый браузер (что не обязательно верно).

0 голосов
/ 12 сентября 2008

до тех пор, пока вы знаете положение 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');
...