web-dev-qa-db-ja.com

window.focus()がGoogleで機能しないChrome

Google Chromeが何らかの時点でwindow.focus()をサポートするかどうか疑問に思う。サポートを意味するとき、私はそれが機能することを意味する。 FireFox、IE6-IE8、Safariなど、他のすべての主要なブラウザーにはこの問題はありません。

ブラウザウィンドウを管理するためのクライアント側クラスがあります。最初にウィンドウを作成すると、ウィンドウがフォーカスを取得しますが、その後ウィンドウにフォーカスを移動しようとしても機能しません。

私の知る限り、これは迷惑なポップアップを避けるためのセキュリティ機能のようであり、Safariで動作するためWebKitの問題ではないようです。

誰かが提案したアイデアの1つは、ウィンドウを閉じてから再び開くことでしたが、これは恐ろしい解決策です。グーグルは、これにイライラしているのは私だけではないことを示しています。

そして、100%明確にするために、タブではなく新しいウィンドウ(私が読んだものからタブにフォーカスすることはできません)と、開かれているすべてのウィンドウが同じドメインにあることを意味します。

上記の悪いアイデア以外のアイデア、回避策はありますか?

これについてChromiumプロジェクトにバグが記録されています。チェックしてください hereRich を投稿してくれてありがとう。

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

私はこの問題に苦労してきました。別のウィンドウへの参照が必要だったため、次を発行していました。

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
Aheho

Windows 7のバージョン14.0.835.202 mでも同じです。エレガントではないが、少なくともページ上のデータが失われないようにする別の回避策を見つけました。フォーカスしたいウィンドウにアラートを表示します。

9
Sti

更新:このソリューションは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();
                }
            }
        }
    }
}
7
nickytonline

focusパラメータとしてjavascript:;を指定してopenを呼び出すことにより、url別のウィンドウを作成できます。

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

// focus that window later on...
window.open('javascript:;', 'myWindow');
3
pwolaq

誰かのブログ からの提案はこれを使用することです:

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

次の このバグ は役に立つかもしれません。

3
Rich Bradshaw

これは私が使用できた回避策です。それはすべての人にとってうまくいくとは限りませんが、私が必要とすることを行い、最初のロード後にポップアップが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は実行されない場合があります。これが問題になる場合は注意して進めてください。

2
tobinibot

子ウィンドウのwindow.focus()は、Chrome v52のWindowsでは問題なく動作しますが、クリックコールバックなどのユーザー開始イベント内でのみ有効です。ブロックされたポップアップはwindow.open()呼び出しに適用されます。)

2
Rich

現在Chromeで動作する唯一の解決策は、新しいウィンドウ内のこのコードです。

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

残念ながら、このソリューションは次の2つの条件でのみ機能します。

  • _window.opener_は、ドキュメントのロード時に名前を設定する必要があります(_window.name="WhateverName";_)
  • window.open()はユーザーがクリックすると呼び出されます
1
Matej Balantič

おそらく誰もが望んでいるものではないかもしれませんが、(クロムで)ポップアップされたページから発生したアラートがポップアップのフォーカスを保持していることに気付きました。だから私は今これをやっている...

ポップアップページで、ヘッダーに関数をロードします。

<script type="text/javascript">
    function confirmBlur() {
        if (confirm("Do you want to close this window?")) {
            window.close();
        }
    }
</script>`

そして、ポップアップされたページで:

<body onblur="ConfirmBlur()">

したがって、これはフォーカスが失われたときにポップアップを閉じる方法の変形です。しかし、私の場合、ポップアップはデータの編集ウィンドウです。窓は、人は尋ねられずに閉じたくない。そのため、ユーザーはフォーカスがドロップされることを通知され、ウィンドウを閉じるかどうかを選択できます。繰り返しになりますが、完璧にはほど遠いですが、それは私にとってはうまくいきました。

(穏やかな)

0
vonDutch

ここでの解決策はどれも役に立たなかった。だから、私はこれを思いついた:

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

これにより、投稿を介してターゲットURLに送信される空白のフォームが作成されます。 target="_blank"を適用することにより、新しいウィンドウにフォーカスを維持するという副作用を伴うwindow.open()の呼び出しを模倣します。

編集:後でフォーム要素も削除するバニラ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);
0
javon27

ここで次のコード行を使用して、再度焦点を合わせます。これは、これまでのところ私にとってうまくいったことです。

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

この回答のおかげで[こちら]( https://stackoverflow.com/a/30758862/10706668 "Dileeparによる回答")

また、テストのために[jsfiddle]( https://jsfiddle.net/Foxygaming9978/6gc38f5x/ "jsfiddle popup refocus testing")も作成しました。

これが役立つことを願っています

0
Zachary Cross

とても簡単な解決策を見つけました。

同じウィンドウ( "_self")をターゲットにして、バックグラウンドの位置にあるウィンドウを再度開くと、Chromeは自動的にそのウィンドウにフォーカスします。

ウィンドウのフォーカスを取り戻すには、次のコードを使用する必要があります。

path = windowHandle.document.URL;
windowHandle.open(path,"_self");
0
Raposo
window.open('javascript:void(0)', 'myWindow');
0
Alex

これは私には問題ありません。キャッチブロックから空のウィンドウの起動を削除し、代わりにURLを直接起動しました。これにより、ユーザーが空のウィンドウを言ったときの混乱を回避できます。

windowHandle = window.open('', 'PrintInvoice', urlOptions);
try {
    windowHandle.document.location.href = url;
} catch (exc) {
    windowHandle.close();
    windowHandle = window.open(url, 'PrintInvoice', urlOptions);
}
windowHandle.focus();
0
Praveena M

これをChromeで戦いました。ユーザーが親画面のリンクをクリックしたときに表示されるポップアップウィンドウが必要でした。ポップアップウィンドウが最初に表示されたときに機能しますが、ポップアップがフォーカスを失うと、javascriptはそれを前面に戻すことができません。ウィンドウを手動でクリックする必要があります。ここに私のために働いたものがあります。このスクリプトは、親ウィンドウ(リンクがあるウィンドウ)です。ご覧のとおり、HEADセクション::

_<script type="text/javascript">
  var infoWindow;

  function openLink(url)   {
    infoWindow = window.open("", "infoWindow", "width=880, height=500, top=20, left=20, scrollbars=yes, toolbar=yes, resizable=yes");
    infoWindow.location.href=url;
    infoWindow.focus();
  }

  function closeWindow()   {
    if (infoWindow)   {
      infoWindow.close();
    }
  }
</script>
</head>
<body bgcolor="black" onFocus="closeWindow()" onLoad="closeWindow()">
_

すべてのリンクは<A href="Javascript: openLink('url')">です。ユーザーがポップアップウィンドウを手動で閉じない場合、親ウィンドウがフォーカスを取り戻すとポップアップウィンドウが閉じられます。そのため、ポップアップは毎回破棄され、再作成されます。ちょっと複雑に思えますが、それは私にとってはうまくいきます。

0
Uncle Mike