[解決済み] Chromeでブロックされたポップアップを検出する
質問
私は、ポップアップが他のブラウザでブロックされているかどうかを検出する javascript のテクニックを知っています ( この質問に対する答え ). ここに基本的なテストがあります。
var newWin = window.open(url);
if(!newWin || newWin.closed || typeof newWin.closed=='undefined')
{
//POPUP BLOCKED
}
しかし、これはChromeではうまくいきません。 ポップアップがブロックされると、"POPUP BLOCKED"セクションに到達することはありません。
もちろん、Chrome は実際にはポップアップをブロックしませんが、右下隅の小さな最小化されたウィンドウでポップアップを開き、ブロックされたポップアップを一覧表示するので、テストはある程度うまくいっています。
私がやりたいことは、ポップアップが Chrome のポップアップ ブロッカーによってブロックされたかどうかを判断できるようにすることです。 私は、機能検出を優先して、ブラウザーのスニッフィングを避けようとしています。ブラウザーのスニッフィングなしでこれを行う方法はありますか?
編集
: 現在、私は
newWin.outerHeight
,
newWin.left
などのプロパティを使って実現します。 Google Chromeは、ポップアップがブロックされた場合、すべてのpositionとheightの値を0として返します。
残念ながら、ポップアップが未知の時間実際に開かれた場合でも、同じ値が返されます。 いくつかの魔法のような期間 (私のテストでは数秒) の後、位置とサイズの情報は正しい値として返されます。 つまり、まだ解明には至っていないのです。 どのようなヘルプでもかまいません。
どのように解決するのですか?
あなたが言う「魔法の時間」とは、おそらくポップアップの DOM が読み込まれたときのことでしょう。あるいは、すべてのもの (画像、外部 CSS など) が読み込まれたときかもしれません。非常に大きなグラフィックをポップアップに追加することで簡単にテストすることができます (最初にキャッシュをクリアしてください!)。jQueryのようなJavascriptフレームワークを使用している場合、ready()イベント(または同様のもの)を使用して、ウィンドウオフセットをチェックする前にDOMがロードされるのを待つことができます。この場合の危険は、Safariの検出が相反する方法で動作することです。SafariではポップアップのDOMは決してready()にならず、開こうとしているウィンドウの有効なハンドルが与えられるため、それが実際に開くかどうかにかかわらず、です。(実際、上記のポップアップのテストコードはサファリでは動作しないと思います。)
あなたができる最善のことは、テストをsetTimeout()でラップして、テストを実行する前にポップアップの読み込みを完了するために3-5秒を与えることだと思います。これは完璧ではありませんが、少なくとも 95% の時間で動作するはずです。
以下は、私がクロスブラウザ検出に使用しているコードで、Chromeの部分を除いたものです。
function _hasPopupBlocker(poppedWindow) {
var result = false;
try {
if (typeof poppedWindow == 'undefined') {
// Safari with popup blocker... leaves the popup window handle undefined
result = true;
}
else if (poppedWindow && poppedWindow.closed) {
// This happens if the user opens and closes the client window...
// Confusing because the handle is still available, but it's in a "closed" state.
// We're not saying that the window is not being blocked, we're just saying
// that the window has been closed before the test could be run.
result = false;
}
else if (poppedWindow && poppedWindow.test) {
// This is the actual test. The client window should be fine.
result = false;
}
else {
// Else we'll assume the window is not OK
result = true;
}
} catch (err) {
//if (console) {
// console.warn("Could not access popup window", err);
//}
}
return result;
}
私が行うことは、親からこのテストを実行し、それを setTimeout() でラップして、子ウィンドウがロードするのに3-5秒を与えることです。子ウィンドウでは、テスト関数を追加する必要があります。
関数 test() {}
ポップアップブロッカー検出器は、"test"関数が子ウィンドウのメンバーとして存在するかどうかを確認するためにテストします。
2015年6月15日に追加されました。
現代的な対処法としては、window.postMessage()を使って、子から親にウィンドウがロードされたことを通知させるのが良いかと思います。アプローチは似ていますが (子が親にロードされたことを伝える)、通信手段は改善されています。私はこれを子からクロスドメインで行うことができました。
$(window).load(function() {
this.opener.postMessage({'loaded': true}, "*");
this.close();
});
親は、このメッセージを使用してリッスンします。
$(window).on('message', function(event) {
alert(event.originalEvent.data.loaded)
});
これが役立つといいのですが。
関連
-
[解決済み] ChromeでCSSカスタムスタイルのボタンから青枠を削除する
-
[解決済み] 要素外でのクリックを検出するにはどうすればよいですか?
-
[解決済み] Chromeの同一生成元ポリシーを無効にする
-
[解決済み] モバイル端末の検出にはどのような方法がありますか?
-
[解決済み] ウェブサイト制作のためのChromeキャッシュの無効化
-
[解決済み] Firefox または Chrome ブラウザから HTTP POST リクエストを手動で送信する方法
-
[解決済み] Chromeを使用してASP.NET Web APIがXMLの代わりにJSONを返すようにするにはどうすればよいですか?
-
[解決済み] Safari、Chrome、IE、Firefox、Operaのブラウザを検出する方法は?
-
[解決済み】自己署名付きlocalhost証明書をChromeが受け入れるようにする方法
-
[解決済み] 上級者向けJavaScript。この関数はなぜ括弧でくくられるのですか?重複
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] ブラウザがポップアップをブロックしているかどうかを検出するにはどうすればよいですか?
-
[解決済み] JSのDateからDay名
-
[解決済み] JavaScript で範囲を作成する - 奇妙な構文
-
[解決済み] 文字列がすべて同じ部分文字列で構成されているかどうかを調べるにはどうすればよいですか?
-
[解決済み] BlobからArrayBufferへ移行する方法
-
[解決済み] 文字列とラベルのローカライズとグローバリゼーションのベストプラクティス【終了しました
-
[解決済み] JavaScriptで長い配列を小さい配列に分割する方法
-
[解決済み] Javascript の parseInt() で先頭のゼロを削除する。
-
[解決済み] <ng-content>が空かどうかを確認する方法は?(これまでのAngular 2+で)
-
[解決済み] JavaScriptデータフォーマット/プリティプリンタ