JavaScript | Web API:ウィンドウ・ブラウザ制御 - タブ操作(open / close)

JavaScript JavaScript
スポンサーリンク

「タブ操作」は「新しい窓を開く権利」と「閉じていい範囲」を理解するところから

JavaScript でのタブ操作は、
window.open()window.close() が中心です。

ただし、ここは ブラウザ側の制限がかなり強い領域 でもあります。
「なんでも勝手に開ける・閉じられる」と思うと痛い目を見ます。

大事なポイントは次の 2 つです。

「ユーザーの操作に紐づいたときだけ、新しいタブを開ける」
「自分が開いたタブ(ウィンドウ)しか閉じられない」

この前提を頭に置きながら、具体的に見ていきましょう。


window.open で新しいタブ(またはウィンドウ)を開く

一番シンプルな使い方

window.open(url, target, features) という形で呼びます。
最低限、url だけ指定すれば動きます。

window.open("https://example.com");
JavaScript

多くのブラウザでは、
これで「新しいタブ」が開きます(設定によっては新しいウィンドウ)。

ただし、ここで重要なのは、
「ユーザーのクリックなどに紐づいていない window.open は、ポップアップブロッカーに止められやすい」
という点です。

ユーザー操作に紐づけるのが基本

例えば、ボタンをクリックしたときに新しいタブを開くなら、こう書きます。

<button id="open">新しいタブを開く</button>
<script>
  const btn = document.querySelector("#open");

  btn.addEventListener("click", () => {
    window.open("https://example.com", "_blank");
  });
</script>

このように、
「クリックイベントの中で window.open を呼ぶ」
という形だと、ブラウザは「ユーザーの意思によるもの」と判断しやすく、
ポップアップブロックに引っかかりにくくなります。

逆に、ページ読み込み直後に勝手に window.open を連発すると、
ほぼ確実にブロックされます。
迷惑サイト対策として、ブラウザがかなり厳しく見ている領域です。

第2引数 target の意味(_blank / _self など)

window.open の第2引数は「どこに開くか」です。

window.open("https://example.com", "_blank"); // 新しいタブ
window.open("https://example.com", "_self");  // 今のタブで開く(location.href と似た動き)
JavaScript

_blank は「新しいタブ(またはウィンドウ)」、
_self は「今のタブ」です。

ふつう「タブを開く」と言ったら _blank を使います。


window.close でタブを閉じるときの大前提

「自分が開いたタブ」しか閉じられない

ここが一番重要です。

JavaScript から window.close() を呼んでも、
「そのページが自分で開いたウィンドウ・タブ」でない限り、ほとんどのブラウザは無視します。

例えば、ユーザーが普通に URL を打って開いたページで、
いきなり window.close() を実行しても、基本的には閉じられません。

これは「勝手にユーザーのタブを閉じられたら困る」からです。
セキュリティ・ユーザー体験の観点で、ブラウザが強く制限しています。

自分で開いたタブなら閉じられる

window.open で開いたウィンドウは、その戻り値としてハンドル(参照)が返ってきます。
それに対して close() を呼ぶと閉じられます。

const win = window.open("https://example.com", "_blank");

// 何かのタイミングで
win.close();
JavaScript

このように、

「自分が open したウィンドウ」
「そのウィンドウを指すオブジェクト(win)」

があれば、close() で閉じることができます。

ただし、これもブラウザや設定によっては制限されることがあるので、
「絶対に閉じられる」とは思わないほうが安全です。


open と close を組み合わせた具体例

ボタンで開いて、別のボタンで閉じる

<button id="open">タブを開く</button>
<button id="close">タブを閉じる</button>

<script>
  let childWindow = null;

  document.querySelector("#open").addEventListener("click", () => {
    if (!childWindow || childWindow.closed) {
      childWindow = window.open("https://example.com", "_blank");
    } else {
      childWindow.focus(); // すでに開いていたら前面に出す
    }
  });

  document.querySelector("#close").addEventListener("click", () => {
    if (childWindow && !childWindow.closed) {
      childWindow.close();
    }
  });
</script>

ここでやっていることは、

window.open の戻り値を childWindow に保存しておく
すでに開いているかどうかを childWindow.closed で確認する
閉じるときは childWindow.close() を呼ぶ

という流れです。

このように「自分が開いたタブ」に対してだけ、
close を使うのが基本です。


「今のタブを閉じる」は基本的にできないと思っておく

window.close() はほぼ効かないケースが多い

例えば、こう書いても、多くのブラウザでは何も起きません。

window.close();
JavaScript

ユーザーが自分で開いたタブを、
JavaScript が勝手に閉じるのは危険だからです。

一部のブラウザや特定の条件(window.open で開かれたタブなど)では動くこともありますが、
「一般的なページで window.close() は効かない」
と考えておくのが現実的です。

「閉じるボタンを作りたい」ときの考え方

たまに「モーダルではなく、本当にタブを閉じるボタンを作りたい」という話が出ますが、
ブラウザの制限を考えると、基本的にはおすすめしません。

代わりに、

「トップページに戻る」ボタンを作る
「前のページに戻る」ボタン(history.back())を作る

といった形で、
「タブを閉じる」のではなく「遷移で戻る」設計にするほうが現実的です。


ポップアップブロッカーと「嫌われないタブ操作」の感覚

なぜブラウザは勝手な open を嫌うのか

昔、悪質なサイトが

ページを開いた瞬間に大量のポップアップを開く
閉じても閉じても新しいウィンドウが出てくる

といったことをしていた時代がありました。

その反省から、
ブラウザは「ユーザーの操作に紐づかない window.open」を
強く制限するようになりました。

だから今は、

ページ読み込み時に勝手に window.open を呼ぶ
タイマーで定期的に window.open を呼ぶ

といったコードは、ほぼ確実にブロックされます。

「ユーザーの意思に沿ったタブ操作」を心がける

タブ操作を設計するときは、
次のような感覚を持っておくと健全です。

ユーザーがクリックした → その結果として新しいタブが開く
ユーザーが「閉じる」ボタンを押した → その結果として自分が開いたタブを閉じる

つまり、
「ユーザーの行動の延長線上にあるタブ操作」 に留める、ということです。

「勝手に開く」「勝手に閉じる」は、
ブラウザにもユーザーにも嫌われる、と思っておくとちょうどいいです。


初心者として「タブ操作(open / close)」で本当に掴んでほしいこと

window.open(url, target) で新しいタブ(またはウィンドウ)を開ける
ただし、ユーザー操作に紐づかない open はポップアップブロッカーに止められやすい
window.close() でタブを閉じられるのは「自分が open したウィンドウ」に基本的に限られる
今のタブを勝手に閉じることは、ほとんどのブラウザでできない(セキュリティ・UX のため)
タブ操作は「ユーザーの意思に沿った動き」に留めるのが健全な設計

一度、簡単なページを作って、

ボタンを押したら window.open でタブを開く
もう一つのボタンで、そのタブを close する

という流れを自分の手で書いてみてください。

「開けるタブ」と「閉じていいタブ」の境界を、
コードとブラウザの挙動で体感できると、
タブ操作に対する感覚が一気にクリアになります。

タイトルとURLをコピーしました