window.focus () не работает в Google Chrome - PullRequest
43 голосов
/ 03 мая 2010

Просто интересно, собирается ли Google Chrome поддерживать window.focus() в какой-то момент.Когда я имею в виду поддержку, я имею в виду это работает.Призыв к этому не провалится, он просто ничего не делает.Все другие основные браузеры не имеют этой проблемы: FireFox, IE6-IE8 и Safari.

У меня есть класс на стороне клиента для управления окнами браузера.Когда я впервые создаю окно, оно фокусируется, но последующие попытки перенести фокус на окно не работают.

Из того, что я могу сказать, это, кажется, функция безопасности, чтобы избежать раздражающих всплывающих окони, похоже, это не проблема WebKit, так как он работает в Safari.

Я знаю, что одна из выдвинутых идей заключалась в том, чтобы закрыть окно, а затем снова открыть его, но это ужасное решение.Поиск в Google показывает, что я не единственный человек, разочарованный этим.

И чтобы быть на 100% ясным, я имею в виду новые окна, а не вкладки (вкладки не могут быть сфокусированы на том, что я прочитал) ивсе открываемые окна находятся в одном домене.

Любые идеи, обходные пути, кроме упомянутого выше плохого?

В проекте Chromium есть ошибка, проверьте ее.вне здесь .Спасибо за сообщение, что Rich .

MyCompany = { UI: {} }; // Put this here if you want to test the code. I create these namespaces elsewhere in code.

MyCompany.UI.Window = new function() {
    // Private fields
    var that = this;
    var windowHandles = {};

    // Public Members
    this.windowExists = function(windowTarget) {
        return windowTarget && windowHandles[windowTarget] && !windowHandles[windowTarget].closed;
    }

    this.open = function(url, windowTarget, windowProperties) {
        // See if we have a window handle and if it's closed or not.
        if (that.windowExists(windowTarget)) {

            // We still have our window object so let's check if the URLs is the same as the one we're trying to load.
            var currentLocation = windowHandles[windowTarget].location;

            if (
                (
                    /^http(?:s?):/.test(url) && currentLocation.href !== url
                )
                    ||
                (
                    // This check is required because the URL might be the same, but absolute,
                    // e.g. /Default.aspx ... instead of http://localhost/Default.aspx ...
                    !/^http(?:s?):/.test(url) &&
                    (currentLocation.pathname + currentLocation.search + currentLocation.hash) !== url
                )
            ) {
                // Not the same URL, so load the new one.
                windowHandles[windowTarget].location = url;
            }

            // Give focus to the window. This works in IE 6/7/8, FireFox, Safari but not Chrome.
            // Well in Chrome it works the first time, but subsequent focus attempts fail,. I believe this is a security feature in Chrome to avoid annoying popups.
            windowHandles[windowTarget].focus();
        }
        else
        {
            // Need to do this so that tabbed browsers (pretty much all browsers except IE6) actually open a new window
            // as opposed to a tab. By specifying at least one window property, we're guaranteed to have a new window created instead
            // of a tab.
            windowProperties = windowProperties || 'menubar=yes,location=yes,width=700, height=400, scrollbars=yes, resizable= yes';
            windowTarget = windowTarget || "_blank";

            // Create a new window.
            var windowHandle = windowProperties ? window.open(url, windowTarget, windowProperties) : window.open(url, windowTarget);

            if (null === windowHandle) {
                alert("You have a popup blocker enabled. Please allow popups for " + location.protocol + "//" + location.host);
            }
            else {
                if ("_blank" !== windowTarget) {
                    // Store the window handle for reuse if a handle was specified.
                    windowHandles[windowTarget] = windowHandle;
                    windowHandles[windowTarget].focus();
                }
            }
        }
    }
}

Ответы [ 15 ]

9 голосов
/ 09 января 2014

Я боролся с этой проблемой. Я хотел ссылку на другое окно, поэтому я выдавал:

otherWinRef = window.open("","OtherWindow");

Однако, когда я выполню эту команду, браузер переключит фокус на OtherWindow. Я думал, что это можно решить, выполнив это:

otherWinRef = window.open("","OtherWindow");
window.focus();

но window.focus () не имеет никакого эффекта. Я попробовал:

otherWinRef = window.open("","OtherWindow");
setTimeout(window.focus,0);

Но вызов window.focus () по-прежнему не имел никакого эффекта.

Я решил проблему, добавив следующий код в источник OtherWindow.

function Bounce(w) {

        window.blur();
        w.focus();
}

Затем я изменил код в главном окне на:

otherWinRef = window.open("","OtherWindow");
otherWinRef.Bounce(window);
9 голосов
/ 31 октября 2011

По-прежнему в версии 14.0.835.202 на Windows 7; нашел другой обходной путь, не более элегантный, но, по крайней мере, позволит избежать потери данных на странице: показать предупреждение в окне, на которое нужно сфокусироваться.

7 голосов
/ 03 мая 2010

ОБНОВЛЕНИЕ: Это решение больше не работает в Chrome.

Невероятно, решение довольно простое. Я пытался разобраться с этой проблемой, по крайней мере, неделю. Все, что вам нужно сделать, это размыть окно и дать ему фокус. Я пробовал это ранее, и это не сработало.

windowHandle.blur();
windowHandle.focus();

Итак, я попробовал это вместо:

windowHandle.blur();
setTimeout(windowHandle.focus, 0);

и это похоже на работу.

Я обновил свой код здесь:

MyCompany = { UI: {} }; // Put this here if you want to test the code. I create these namespaces elsewhere in code.

MyCompany.UI.Window = new function() {       
    // Private fields
    var that = this;
    var windowHandles = {};
    var isChrome = /chrome/.test(navigator.userAgent.toLowerCase());

    // Public Members
    this.focus = function(windowHandle) {
        if (!windowHandle) {
            throw new Exception("Window handle can not be null.");
        }

        if (isChrome) {
            windowHandle.blur();
            setTimeout(windowHandle.focus, 0);                    
        }
        else {
            windowHandle.focus();
        }    
    }

    this.windowExists = function(windowTarget) {
        return windowTarget && windowHandles[windowTarget] && !windowHandles[windowTarget].closed;
    }

    this.open = function(url, windowTarget, windowProperties) {
        // See if we have a window handle and if it's closed or not.
        if (that.windowExists(windowTarget)) {

            // We still have our window object so let's check if the URLs is the same as the one we're trying to load.
            var currentLocation = windowHandles[windowTarget].location;

            if (
                (
                    /^http(?:s?):/.test(url) && currentLocation.href !== url
                )
                    ||
                (
                    // This check is required because the URL might be the same, but absolute,
                    // e.g. /Default.aspx ... instead of http://localhost/Default.aspx ...
                    !/^http(?:s?):/.test(url) &&
                    (currentLocation.pathname + currentLocation.search + currentLocation.hash) !== url
                )
            ) {
                // Not the same URL, so load the new one.
                windowHandles[windowTarget].location = url;
            }

            // Give focus to the window. This works in IE 6/7/8, FireFox, Safari but not Chrome.
            // Well in Chrome it works the first time, but subsequent focus attempts fail,. I believe this is a security feature in Chrome to avoid annoying popups.
            that.focus(windowHandles[windowTarget]);
        }
        else {
            // Need to do this so that tabbed browsers (pretty much all browsers except IE6) actually open a new window
            // as opposed to a tab. By specifying at least one window property, we're guaranteed to have a new window created instead
            // of a tab.
            //windowProperties = windowProperties || 'menubar=yes,location=yes,width=700, height=400, scrollbars=yes, resizable= yes';
            windowProperties = windowProperties || 'menubar=yes,location=yes,width=' + (screen.availWidth - 15) + ', height=' + (screen.availHeight - 140) + ', scrollbars=yes, resizable= yes';
            windowTarget = windowTarget || "_blank";

            // Create a new window.
            var windowHandle = windowProperties ? window.open(url, windowTarget, windowProperties) : window.open(url, windowTarget);

            if (null === windowHandle || !windowHandle) {
                alert("You have a popup blocker enabled. Please allow popups for " + location.protocol + "//" + location.host);
            }
            else {
                if ("_blank" !== windowTarget) {
                    // Store the window handle for reuse if a handle was specified.
                    windowHandles[windowTarget] = windowHandle;
                    windowHandles[windowTarget].focus();
                }
            }
        }
    }
}
3 голосов
/ 29 ноября 2016

Вы можете focus другое окно, вызвав open с javascript:; как url параметр:

window.open('http://....', 'myWindow');

// focus that window later on...
window.open('javascript:;', 'myWindow');
3 голосов
/ 03 мая 2010

Предложение от чьего-то блога заключается в том, чтобы использовать это:

if (navigator.userAgent.indexOf('Chrome/') > 0) {
    if (window.detwin) {
        window.detwin.close();
        window.detwin = null;
    }
}
window.detwin = window.open(URL,  'windowname', '...');
window.detwin.focus();

После эта ошибка может быть полезной.

2 голосов
/ 26 августа 2016

window.focus() для дочерних окон прекрасно работает для меня в Chrome v52 в Windows, но ТОЛЬКО внутри инициируемого пользователем события, например обратный звонок (Это то же самое ограничение, которое блокируется всплывающим окном для window.open() вызовов.)

2 голосов
/ 15 февраля 2012

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

function refocusWindow() {
  var newName = window.name + '-2'; // you'll want to customize this for your needs
  var options = ''; // again, customize for your situation
  var w = window.open('', newName, options);
  w.document.write(document.getElementById('everything').innerHTML);
  window.close();
}    

Я использую трюк с новым окном, чтобы он выглядел так, будто я просто перефокусирую страницу, но на самом деле я создаю новое окно с точным содержимым старого окна, а затемзакрытие старого окна.

Вам просто нужно убедиться, что вы можете захватить все необходимое для нового окна.Я положил все, что мне нужно, в #everything div;вам, возможно, придется изменить это для своих нужд.

Надеюсь, что это по крайней мере поможет некоторым из вас.

Примечание : встроенный Javascript, кажется, выполняется с таким подходом, связанных Javascript, возможно, нет.Действуйте с осторожностью, если это будет проблемой для вас.

1 голос
/ 12 марта 2013

Единственное решение, которое в настоящее время работает в Chrome - это код в новом окне:

$(".closeBtn").click( function(e) 
{
    window.open("",window.opener.name);
    window.close();
});

К сожалению, решение работает только при двух условиях:

  • window.opener должно быть установлено его имя при загрузке документа (window.name="WhateverName";)
  • window.open() вызывается по клику пользователя
0 голосов
/ 24 мая 2019

Я просто использую эту строку кода здесь, чтобы перефокусировать, это лучшее, что до сих пор работало для меня:

window.open('', 'NameOfTheOpenedWindow').focus();

благодаря этому ответу [здесь] (https://stackoverflow.com/a/30758862/10706668"Answer от dileepar ")

Я также сделал [jsfiddle] (https://jsfiddle.net/Foxygaming9978/6gc38f5x/"jsfiddle тестирование всплывающего окна ") для тестирования.

Надеюсь, это поможет

0 голосов
/ 13 ноября 2018

Ни одно из решений здесь не сработало для меня. Итак, я придумал это:

$('<form target="_blank" action="'+URL+'" method="post"></form>')
    .appendTo('body').submit();

Это создает пустую форму, которая отправляется по почте на целевой URL. Применяя target="_blank", мы имитируем вызов window.open () с побочным эффектом сохранения фокуса на новом окне.

Редактировать: версия Vanilla JS, которая впоследствии также удаляет элемент формы:

var f = document.createElement("form");
f.setAttribute('method', 'post');
f.setAttribute('action', URL);
f.setAttribute('target', '_blank');
document.getElementsByTagName('body')[0].appendChild(f);
f.submit();
f.parentNode.removeChild(f);
...