したいこと
親画面から子画面のポップアップをしたい。
子画面が無ければ新規で起動し、あればそれをアクティブにする。
(つまり開く子画面は1つのみであり、無限増殖しない。)
困った現象
ほとんどのブラウザは以下の方法でOKだったはずですが・・・
親画面
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>旧 親画面</title>
<script>
function winOpen() {
window.open( 'old2.html', 'old2' ).focus;
}
</script>
</head>
<body>
<div>
旧 親画面
</div>
<div>
<button onclick="winOpen();">子画面起動</button>
</div>
</body>
</html>
子画面
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>旧 子画面</title>
<script>
</script>
</head>
<body>
<div>
旧 子画面です
</div>
</body>
</html>
でも iPhone の safari の場合、ポップアップ後、子画面をそのままにして、親画面に戻って、再度ポップアップしても、子画面がアクティブになりません。
また他のPCやブラウザでも、子画面をそのままにして、親画面に戻って親画面をリロード(あるいは再起動)したら、再度ポップアップしても既存の子画面がアクティブにならず、新規で子画面が起動してしまいます。
解決策
トリッキーな方法ですが、以下の方法で解決できると思います。
親画面
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>新 親画面</title>
<script>
var winPopup;
window.addEventListener( 'pagehide', winClean );
function winClean() {
window.open( 'new3.html', 'new2' );
}
function winOpen() {
if ( winPopup ) {
if ( ! winPopup.closed ) {
winPopup.close();
}
}
winPopup = window.open( 'new2.html', 'new2' );
}
</script>
</head>
<body>
<div>
新 親画面
</div>
<div>
<button onclick="winOpen();">子画面起動</button>
</div>
</body>
</html>
子画面
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>新 子画面</title>
<script>
</script>
</head>
<body>
<div>
新 子画面です
</div>
</body>
</html>
ダミー画面
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ダミー画面</title>
<script>
window.addEventListener( 'load', winClean );
function winClean() {
window.close();
}
</script>
</head>
<body>
<div>
ダミー画面
</div>
</body>
</html>
ダミー画面は、お掃除用画面です。
子画面が残らないよう強制的にクローズします。
じつは親子間でドメインが異なると、うまくポップアップできない場合があるのですが、ダミー画面はその問題を解消してくれます。
(親子が同じドメインなら、ダミー画面は要らないはず。)
これで iPhone の safari を含むすべてのブラウザで、
親画面から子画面のポップアップができるはずです。
参考
2回目以降のwindow.openでの各ブラウザでのフォーカスについて
ページのコンテンツから離れたタイミングのブラウザイベントの選び方