JavaScriptでリンクを別ウインドウ・タブで開くには?window.openの使い方・サンプルコード付き!

js-open-window javascript

JavaScriptを使った別ウインドウのオープン、基本的なことは知っているけれど、いざ実装しようとすると細かい仕様を忘れていた…そんな経験、ありませんか?

特にwindow.open()の使い方ひとつとっても、単純なリンクだけではなく、ウインドウサイズや位置を制御したり、ポップアップブロックを回避する工夫が求められる場面もあります。さらに、ブラウザによる挙動の違いや、セキュリティ上必須のnoopenernoreferrer属性の対応など、中級以上の制作者でもつまずきやすいポイントが意外と多いのが実情です。

この記事では、JavaScriptで別ウインドウを開く実装に必要な知識を総整理しています。基本の使い方から、featuresパラメータによる細かなウインドウ制御、開いたウインドウへのスクリプト操作、ブラウザ間の互換性対応までを網羅。

また、実運用を想定し、ポップアップブロッカー対策や安全なウインドウオープン方法、開いたウインドウにパラメータを渡すケースにも触れています。そのまま使えるサンプルコードも多数用意しているので、知識のアップデートと実装の両方に役立てていただけます。

この記事を読んでわかること

  • window.open()の使い方とfeatures指定のまとめ
  • タブではなく「完全な別ウインドウ」で開くための実装ポイント
  • ウインドウサイズ・位置の指定方法と注意点
  • 開いたウインドウとのデータ連携・操作テクニック
  • ブラウザごとの仕様差異と実装時の落とし穴
  • ポップアップブロックを回避しながらユーザー体験を損なわない方法

「一度学んだけど、ちゃんとできるか少し不安…」「今のベストプラクティスを押さえたい」そんな方に、ぴったりの内容です。ぜひ参考にしてみてください!

  1. JavaScriptで別ウインドウを開く方法【window.open徹底解説】
    1. window.open()メソッドとは?最もシンプルな開き方
    2. 新しいタブではなく「別ウィンドウ」として開くためのポイント
  2. window.openのオプション指定でサイズ・位置・表示を制御
    1. 開くウィンドウの横幅(width)と高さ(height)を指定する
    2. ウィンドウを画面上の特定の位置(left, top)に表示する
    3. アドレスバーやツールバーなど、表示/非表示を制御するfeaturesパラメータ一覧
  3. JavaScriptで開いた別ウィンドウを操作・情報を取得する
    1. window.open()の戻り値(WindowProxyオブジェクト)とは
    2. 開いた別ウィンドウのURLを変更したり、強制的に閉じる(window.close())方法
    3. 元のウィンドウから、開いたウィンドウ内の要素や関数にアクセスする方法
  4. 別ウインドウで開くJavaScript実装時の注意点とトラブルシューティング
    1. ポップアップブロッカーでブロックされる原因と回避策
    2. 主要ブラウザ(Chrome, Firefox, Safari, Edge)での互換性について
    3. 開くURLにパラメータ(クエリストリング)を付けて渡す方法
  5. 【コピペで使える】別ウインドウを開くJavaScriptサンプルコード集
    1. 基本的な別ウィンドウの開き方コード例
    2. サイズ・位置・オプションを指定して開く応用コード例
    3. ボタンクリックで別ウィンドウを開くイベントリスナーの設置方法
    4. 応用例:実用的なシナリオ別サンプル
  6. まとめ

JavaScriptで別ウインドウを開く方法【window.open徹底解説】

window.open()メソッドとは?最もシンプルな開き方

JavaScriptを使ってWebページから別のウインドウやタブを開きたいと思ったことはありませんか?そんなときに便利なのがwindow.open()メソッドです。このメソッドを使えば、ボタンをクリックしたときに新しいウインドウを開いたり、特定の条件で別ページを表示したりと、ユーザー体験を向上させる様々な機能を実装できます。

Window: open() メソッド - Web API | MDN
open() は Window インターフェイスのメソッドで、指定されたリソースを、新しい、または既存の指定された名前を持った閲覧コンテキスト (ウィンドウ、 iframe、タブ) に読み込みます。

window.open()は、JavaScriptの標準メソッドで、どのブラウザでも利用可能な基本的な機能です。最もシンプルな使い方は次のとおりです:

window.open('<https://example.com>');

たったこれだけで、指定したURLが新しいタブまたはウインドウで開きます。デフォルトでは多くの現代のブラウザでは新しいタブとして開かれますが、これはブラウザの設定によって変わることもあります。

少し詳しく見てみましょう。window.open()メソッドは、最大で3つのパラメータを受け取ることができます:

window.open(url, windowName, windowFeatures);
  • url: 開きたいページのURL
  • windowName: 新しいウインドウの名前(ターゲット名)
  • windowFeatures: ウインドウの特性を指定する文字列(サイズ、位置など)

例えば、特定の名前をつけてウインドウを開く場合は次のように書きます:

window.open('<https://example.com>', 'exampleWindow');

名前をつけることで、同じ名前で再度window.open()を呼び出したときに、新しいウインドウを開くのではなく、既に開いているウインドウのURLを変更することができます。これはユーザー体験を考えると重要なポイントです。

また、window.open()は戻り値として、開いたウインドウを制御するためのWindowProxyオブジェクトを返します。これを変数に格納しておくことで、後から開いたウインドウを操作することも可能です:

const newWindow = window.open('<https://example.com>');
// 後でnewWindowを使って操作できる

新しいタブではなく「別ウィンドウ」として開くためのポイント

最近のブラウザでは、ユーザーの利便性を考慮して、window.open()を実行すると多くの場合は新しいタブとして開かれます。しかし、アプリケーションの要件によっては、明確に分離された別ウインドウとして開きたい場合もあるでしょう。

別ウインドウとして確実に開くためには、第3引数のwindowFeaturesパラメータを適切に設定する必要があります:

window.open('<https://example.com>', 'exampleWindow', 'width=800,height=600');

上記のようにwidthheightなどのサイズ指定を入れることで、多くのブラウザでは新しいウインドウとして開かれる可能性が高まります。特に以下のような指定を加えるとより効果的です:

window.open('<https://example.com>', 'exampleWindow', 'width=800,height=600,resizable=yes,scrollbars=yes');

ただし、これは絶対的な保証ではなく、最終的にはブラウザの設定やユーザーの好みに依存する部分があります。例えば、Chromeのユーザー設定で「ポップアップを常に新しいタブで開く」を有効にしている場合は、どのような指定をしても新しいタブとして開かれます。

また、モバイルブラウザでは、画面サイズの制約から、window.open()は通常新しいタブとして処理されることがほとんどです。これはモバイル環境の制約として覚えておく必要があります。

さらに、確実に別ウインドウとして開くためのもう一つのテクニックとして、window.open()を呼び出す際に第2引数(ウインドウ名)をユニークな値にすることも効果的です:

window.open('<https://example.com>', 'uniqueWindowName_' + Date.now(), 'width=800,height=600');

このように、タイムスタンプなどを使って毎回異なる名前を生成することで、常に新しいウインドウが作成される可能性が高まります。

ただし、前述のとおり、最終的なユーザー体験はブラウザの設定に依存する部分があるため、アプリケーションの設計においては、新しいタブで開かれる可能性も考慮しておくことが望ましいでしょう。

window.openのオプション指定でサイズ・位置・表示を制御

JavaScriptでwindow.open()メソッドを使用するとき、単に新しいウィンドウを開くだけでなく、そのウィンドウの見た目や振る舞いをきめ細かく制御できることをご存知でしょうか?

基本的なwindow.open()の構文は次のようになっています:

window.open(url, name, features);

ここで重要なのは3番目のパラメータ「features」です。このパラメータを使いこなすことで、開くウィンドウのサイズや位置、表示される要素などを自由自在にカスタマイズできます。まるでウィンドウのリモコンを手に入れたようなものです!

それでは、具体的なオプション設定方法を見ていきましょう。

開くウィンドウの横幅(width)と高さ(height)を指定する

新しく開くウィンドウのサイズを指定したい場合は、widthheightパラメータを使用します。値はピクセル単位で指定します。

// 幅800px、高さ600pxの新しいウィンドウを開く
const newWindow = window.open('<https://example.com>', '_blank', 'width=800,height=600');

ここで注意すべき点がいくつかあります:

  • パラメータはカンマで区切り、スペースは入れません('width=800,height=600'
  • 各ブラウザには最小サイズの制限があり、極端に小さいサイズは強制的に調整されることがあります
  • ディスプレイの解像度より大きなサイズを指定した場合、ブラウザは自動的に調整します

実用的なサイズ設定としては、デスクトップ向けのアプリケーションであれば800×600から1200×800程度、小さめのツールウィンドウであれば400×300程度が使いやすいでしょう。

また、ユーザーの環境に合わせて動的にサイズを決定するテクニックもあります:

// 画面幅の80%、高さの70%のサイズでウィンドウを開く
const screenWidth = window.screen.width;
const screenHeight = window.screen.height;
const width = Math.round(screenWidth * 0.8);
const height = Math.round(screenHeight * 0.7);

const newWindow = window.open('<https://example.com>', '_blank', `width=${width},height=${height}`);

このように可変的なサイズ指定をすることで、様々な画面サイズのデバイスでも適切なウィンドウサイズを維持できます。

ウィンドウを画面上の特定の位置(left, top)に表示する

ウィンドウのサイズだけでなく、画面上のどの位置に表示するかも指定できます。これにはlefttopパラメータを使用します。

// 画面の左上から100pxずつ離れた位置にウィンドウを表示
const newWindow = window.open('<https://example.com>', '_blank', 'width=800,height=600,left=100,top=100');

座標系は画面の左上が原点(0,0)となっており、右に行くほどleftの値が大きくなり、下に行くほどtopの値が大きくなります。

実用的な位置指定のテクニックとして、画面の中央にウィンドウを配置する方法があります:

// ウィンドウを画面中央に配置
const width = 800;
const height = 600;
const left = (screen.width - width) / 2;
const top = (screen.height - height) / 2;

const newWindow = window.open(
  '<https://example.com>',
  '_blank',
  `width=${width},height=${height},left=${left},top=${top}`
);

このコードでは、画面サイズからウィンドウサイズを引いて2で割ることで、中央に配置するための座標を計算しています。これにより、ユーザーの画面サイズに関わらず常にウィンドウが中央に表示されるようになります。

また、複数のウィンドウを開く場合は、少しずつずらして表示させるテクニックも便利です:

let offsetX = 0;
let offsetY = 0;

function openNewWindowWithOffset() {
  const newWindow = window.open(
    '<https://example.com>',
    '_blank',
    `width=400,height=300,left=${100 + offsetX},top=${100 + offsetY}`
  );

  // 次に開くウィンドウの位置をずらす
  offsetX += 40;
  offsetY += 40;
}

アドレスバーやツールバーなど、表示/非表示を制御するfeaturesパラメータ一覧

window.open()のfeaturesパラメータでは、サイズと位置だけでなく、ウィンドウに表示される様々な要素の表示/非表示も制御できます。これにより、必要な機能だけを持つカスタムウィンドウを作成できます。

主要なfeaturesパラメータは以下の通りです:

パラメータ名説明
toolbarツールバーの表示yes/no または 1/0
locationアドレスバーの表示yes/no または 1/0
directories「ディレクトリボタン」または「ブックマークバー」の表示yes/no または 1/0
statusステータスバーの表示yes/no または 1/0
menubarメニューバーの表示yes/no または 1/0
scrollbarsスクロールバーの表示(必要な場合)yes/no または 1/0
resizableウィンドウサイズの変更可否yes/no または 1/0

実際に使用する例を見てみましょう:

// アドレスバーやツールバーを非表示にしたシンプルなウィンドウ
const cleanWindow = window.open(
  '<https://example.com>',
  '_blank',
  'width=800,height=600,toolbar=no,location=no,status=no,menubar=no,scrollbars=yes,resizable=yes'
);

このコードで開かれるウィンドウは、余計な要素がなくコンテンツに集中できる環境になります。ただし、このようなカスタマイズはセキュリティ上の理由から、最新のブラウザでは制限されていることが多いです。特に、ユーザーが明示的なアクションを起こさずに実行された場合(ページ読み込み時の自動実行など)は無視される傾向があります。

さらに高度なオプションもあります:

  • fullscreen=yes – フルスクリーンモードでウィンドウを開く(ただし多くのブラウザでサポートされていない)
  • noopener=yes – 新しいウィンドウと元のウィンドウとの関係を切る(セキュリティ対策)
  • noreferrer=yes – リファラー情報を新しいウィンドウに送信しない

例えば、セキュリティを考慮したウィンドウの開き方は次のようになります:

// セキュリティを考慮したウィンドウの開き方
const secureWindow = window.open(
  '<https://example.com>',
  '_blank',
  'width=800,height=600,noopener=yes,noreferrer=yes'
);

このように、window.open()のオプション指定を活用することで、単に新しいウィンドウを開くだけでなく、その見た目や振る舞いを細かく制御できます。特定の機能だけを持つ専用の作業ウィンドウや、メインウィンドウの邪魔にならない補助ウィンドウなど、用途に応じた最適なウィンドウ設計が可能になります。

ただし、前述の通り、現代のブラウザではセキュリティとユーザー体験の保護のため、これらのオプションが制限されていることがあります。特にポップアップブロッカーとの兼ね合いや、ブラウザごとの対応の違いには注意が必要です。実装する際は、主要なブラウザでのテストを忘れずに行いましょう。

JavaScriptで開いた別ウィンドウを操作・情報を取得する

別ウィンドウを開いたあと、そのウィンドウを操作したり情報を取得したりする必要が出てくることがあります。例えば、別ウィンドウでユーザーが何か操作を行い、その結果を元のウィンドウに反映させるようなケースです。JavaScriptでは、開いたウィンドウへの参照を保持しておくことで、様々な操作が可能になります。

window.open()の戻り値(WindowProxyオブジェクト)とは

window.open()メソッドを実行すると、戻り値として「WindowProxy」オブジェクトが返されます。これは、開いたウィンドウへの参照であり、このオブジェクトを通じて様々な操作が可能になります。

// 新しいウィンドウを開き、その参照を変数に保存する
const newWindow = window.open('<https://example.com>', '_blank', 'width=800,height=600');

// この newWindow 変数を使って、開いたウィンドウを操作できる

このnewWindow変数は、開いたウィンドウのwindowオブジェクトへの参照です。注意点として、異なるオリジン(ドメイン)のページを開いた場合、セキュリティ上の理由から操作できる内容に制限がかかります。これは「同一オリジンポリシー(Same-Origin Policy)」と呼ばれるセキュリティの仕組みです。

もしwindow.open()がポップアップブロッカーによってブロックされた場合や、ユーザーが既に閉じてしまった場合は、戻り値がnullになることがあります。そのため、操作を行う前には必ず戻り値をチェックするのが安全です:

const newWindow = window.open('<https://example.com>', '_blank');

// 開いたウィンドウが存在するか確認してから操作
if (newWindow && !newWindow.closed) {
  // ウィンドウが正常に開かれていて、まだ閉じられていない場合の処理
  newWindow.focus(); // 例:ウィンドウにフォーカスを当てる
} else {
  console.log('ウィンドウを開けなかったか、既に閉じられています');
}

開いた別ウィンドウのURLを変更したり、強制的に閉じる(window.close())方法

WindowProxyオブジェクトを使用すると、開いたウィンドウのURLを変更したり、ウィンドウを閉じたりすることができます。

URLの変更方法:

// 新しいウィンドウを開く
const newWindow = window.open('<https://example.com>', '_blank');

// 数秒後に別のURLに移動させる
setTimeout(() => {
  if (newWindow && !newWindow.closed) {
    newWindow.location.href = '<https://example.org/newpage>';
  }
}, 3000); // 3秒後

このコードでは、最初にexample.comを開き、3秒後にexample.org/newpageに移動させています。newWindow.location.hrefを変更することで、ウィンドウに表示されるURLを制御できます。

ウィンドウを閉じる方法:

// 新しいウィンドウを開く
const newWindow = window.open('<https://example.com>', '_blank');

// 5秒後にウィンドウを閉じる
setTimeout(() => {
  if (newWindow && !newWindow.closed) {
    newWindow.close(); // ウィンドウを閉じる
    console.log('ウィンドウを閉じました');
  }
}, 5000); // 5秒後

newWindow.close()メソッドを呼び出すことで、JavaScriptからプログラム的にウィンドウを閉じることができます。ただし、スクリプトによって開かれたウィンドウでなければ閉じることができないという制限があります。つまり、ユーザーが手動で開いたウィンドウをスクリプトから閉じることはできません。

ウィンドウが閉じられたかの確認:

// ウィンドウが閉じられたかどうかをチェック
function checkWindowStatus() {
  if (newWindow && !newWindow.closed) {
    console.log('ウィンドウはまだ開いています');
  } else {
    console.log('ウィンドウは閉じられました');
    // ウィンドウが閉じられた時の処理
    clearInterval(checkInterval); // チェックを停止
  }
}

// 1秒ごとにウィンドウの状態をチェック
const checkInterval = setInterval(checkWindowStatus, 1000);

newWindow.closedプロパティは、ウィンドウが閉じられている場合にtrueを返します。これを定期的にチェックすることで、ユーザーがウィンドウを閉じたタイミングを検知できます。

元のウィンドウから、開いたウィンドウ内の要素や関数にアクセスする方法

開いたウィンドウの内容を操作するには、DOM要素へのアクセスや関数の実行が必要になることがあります。ただし、これは同一オリジンのページでのみ可能です。

別ウィンドウのDOM要素を操作する:

// 新しいウィンドウを開き、HTMLを設定する
const newWindow = window.open('', '_blank', 'width=400,height=300');
newWindow.document.write('<html><body><h1 id="title">テストページ</h1><div id="content"></div></body></html>');
newWindow.document.close(); // document.writeの後は必ずcloseする

// 別ウィンドウの要素を取得して操作
const titleElement = newWindow.document.getElementById('title');
if (titleElement) {
  titleElement.style.color = 'blue';
  titleElement.textContent = '更新されたタイトル';
}

// 新しい要素を追加
const contentDiv = newWindow.document.getElementById('content');
if (contentDiv) {
  const paragraph = newWindow.document.createElement('p');
  paragraph.textContent = '親ウィンドウから追加されたテキストです。';
  contentDiv.appendChild(paragraph);
}

このコードでは、新しいウィンドウを開き、その中のHTML要素を操作しています。タイトルの色とテキストを変更し、新しい段落要素を追加しています。

別ウィンドウで関数を実行する:

// 新しいウィンドウを開き、関数を定義する
const newWindow = window.open('', '_blank');
newWindow.document.write(`
  <html>
    <head>
      <title>関数テスト</title>
      <script>
        function sayHello(name) {
          document.getElementById('output').textContent = 'こんにちは、' + name + 'さん!';
          return '関数が実行されました';
        }
      </script>
    </head>
    <body>
      <div id="output">ここにメッセージが表示されます</div>
    </body>
  </html>
`);
newWindow.document.close();

// 少し待ってから別ウィンドウの関数を実行
setTimeout(() => {
  if (newWindow && !newWindow.closed) {
    // 別ウィンドウで定義された関数を呼び出す
    const result = newWindow.sayHello('JavaScript');
    console.log('戻り値:', result);
  }
}, 1000); // 1秒待つ

このコードでは、別ウィンドウ内で定義されたsayHello関数を親ウィンドウから呼び出しています。関数の戻り値も取得できます。

子ウィンドウから親ウィンドウを操作する:

逆に、開かれた子ウィンドウから親ウィンドウを操作することも可能です。子ウィンドウからはwindow.openerを通じて親ウィンドウにアクセスできます。

// 親ウィンドウ側のコード
function updateParentStatus(message) {
  document.getElementById('status').textContent = message;
}

// 新しいウィンドウを開く
const newWindow = window.open('', '_blank');
newWindow.document.write(`
  <html>
    <body>
      <h2>子ウィンドウ</h2>
      <button onclick="notifyParent()">親ウィンドウに通知</button>

      <script>
        function notifyParent() {
          // window.opener は親ウィンドウへの参照
          if (window.opener && !window.opener.closed) {
            window.opener.updateParentStatus('子ウィンドウからのメッセージを受信: ' + new Date().toLocaleTimeString());
            window.opener.focus(); // 親ウィンドウにフォーカスを戻す
          }
        }
      </script>
    </body>
  </html>
`);
newWindow.document.close();

この例では、子ウィンドウ内のボタンをクリックすると、親ウィンドウのupdateParentStatus関数が呼び出され、親ウィンドウ内の要素が更新されます。

データの受け渡し:

別ウィンドウとのデータのやり取りには、グローバル変数やローカルストレージ、メッセージングAPIなど、複数の方法があります。

// 親ウィンドウでグローバル変数を定義
window.sharedData = {
  message: 'これは共有データです',
  count: 0
};

// 新しいウィンドウを開く
const newWindow = window.open('', '_blank');
newWindow.document.write(`
  <html>
    <body>
      <h2>データ表示ウィンドウ</h2>
      <div id="data-display"></div>
      <button id="increment">カウントアップ</button>

      <script>
        // 親のデータを表示する関数
        function displayParentData() {
          if (window.opener && window.opener.sharedData) {
            const data = window.opener.sharedData;
            document.getElementById('data-display').textContent =
              'メッセージ: ' + data.message + ', カウント: ' + data.count;
          }
        }

        // 初期表示
        displayParentData();

        // ボタンクリックでカウントアップ
        document.getElementById('increment').addEventListener('click', function() {
          if (window.opener && window.opener.sharedData) {
            window.opener.sharedData.count++;
            displayParentData();
          }
        });
      </script>
    </body>
  </html>
`);
newWindow.document.close();

このコードでは、親ウィンドウで定義したsharedDataオブジェクトを子ウィンドウから参照・更新しています。子ウィンドウのボタンをクリックするとカウンターが増加し、その変更がすぐに表示に反映されます。

以上のように、window.open()メソッドの戻り値を活用することで、JavaScriptから別ウィンドウを様々な方法で操作できます。これにより、複数のウィンドウを連携させた高度なWebアプリケーションの開発が可能になります。ただし、セキュリティ上の制限や、ブラウザの挙動の違いには常に注意が必要です。

別ウインドウで開くJavaScript実装時の注意点とトラブルシューティング

JavaScriptで別ウィンドウを開く実装は一見シンプルですが、実際の運用ではいくつかの課題に直面することがあります。この章では、window.open()を使用する際の主な注意点とトラブルシューティングについて解説します。適切な対処法を知っておくことで、ユーザーにストレスフリーな体験を提供できるでしょう。

ポップアップブロッカーでブロックされる原因と回避策

現代のブラウザは、ユーザー体験を向上させるためにポップアップブロッカーを標準で搭載しています。これは不要な広告や悪意のあるウィンドウからユーザーを保護する一方で、正当な目的のwindow.open()もブロックしてしまうことがあります。

ブロックされる主な原因:

  1. ユーザーの操作なしに実行される – ページ読み込み時やsetTimeoutなどの自動実行
  2. 複数のポップアップを同時に開こうとする – 短時間に複数のウィンドウを開く
  3. 不審なURLパターン – 広告によく使われるドメインやパターン

回避策:

最も確実な回避策は、ユーザーの明示的なアクション(クリックやタップ)に応じてwindow.open()を実行することです。これにより、ほとんどのブラウザではポップアップとして認識されず、ブロックを回避できます。

// NG例: ページ読み込み時に自動実行(ブロックされる可能性大)
window.onload = function() {
  window.open('<https://example.com>', '_blank');
};

// OK例: ユーザーのクリックイベントで実行(ブロックされにくい)
document.getElementById('openWindow').addEventListener('click', function() {
  window.open('<https://example.com>', '_blank');
});

ポップアップがブロックされた場合の検出と対応:

window.open()がブロックされた場合、戻り値がnullになるか、例外が発生することがあります。これを検出して、ユーザーに適切なガイダンスを提供しましょう。

function safeWindowOpen(url, name, features) {
  try {
    const newWindow = window.open(url, name, features);

    if (newWindow === null || typeof newWindow === 'undefined') {
      alert('ポップアップがブロックされました。このサイトのポップアップを許可してください。');
      return null;
    }

    // 新しいウィンドウが開かれたが、アクセスできない場合(別オリジンなど)
    if (newWindow.closed || newWindow.closed === undefined) {
      alert('ポップアップウィンドウを開くことができませんでした。ブラウザの設定を確認してください。');
      return null;
    }

    return newWindow;
  } catch (e) {
    console.error('ウィンドウを開く際にエラーが発生しました:', e);
    alert('ウィンドウを開けませんでした。ポップアップブロックの設定を確認してください。');
    return null;
  }
}

// 使用例
document.getElementById('openWindow').addEventListener('click', function() {
  const win = safeWindowOpen('<https://example.com>', '_blank', 'width=800,height=600');
  if (win) {
    console.log('ウィンドウが正常に開かれました');
  }
});

代替アプローチ:

どうしてもポップアップが必要な場合、ユーザーに事前に通知する方法も効果的です。

// 2段階アプローチ
document.getElementById('preparePopup').addEventListener('click', function() {
  // まず通知を表示
  const infoElement = document.createElement('div');
  infoElement.innerHTML = `
    <p>次にポップアップウィンドウを開こうとします。ブロックされた場合は、ブラウザの通知を確認し、
    「常に許可」または「このサイトのポップアップを許可」を選択してください。</p>
    <button id="proceedWithPopup">続行する</button>
  `;
  document.body.appendChild(infoElement);

  // 続行ボタンで実際にポップアップを開く
  document.getElementById('proceedWithPopup').addEventListener('click', function() {
    window.open('<https://example.com>', '_blank', 'width=800,height=600');
  });
});

主要ブラウザ(Chrome, Firefox, Safari, Edge)での互換性について

各ブラウザはwindow.open()の実装や扱いが微妙に異なります。クロスブラウザの互換性を確保するには、これらの違いを理解しておく必要があります。

Chrome:

  • ポップアップブロックが最も厳格な傾向
  • 特定のfeaturesパラメータ(toolbar, location等)の効果が限定的
  • 全画面モード(fullscreen=yes)がサポートされていない

Firefox:

  • 比較的柔軟なポップアップポリシー
  • featuresパラメータの多くをサポート
  • window.open()のセキュリティチェックが厳格

Safari:

  • モバイル版Safari特有の制限あり(iOS)
  • 新しいタブとして開かれることが多い
  • macOSではwindow.open()のオプションが最も効果的に機能する傾向

Edge (Chromium版):

  • Chromeとほぼ同様の動作
  • 企業ポリシーによる追加制限がある場合も

ブラウザ間の互換性を高めるテクニック:

  • 最低限の共通featuresに絞る
// クロスブラウザで比較的安定して動作するオプション
const commonFeatures = 'width=800,height=600,resizable=yes,scrollbars=yes';
window.open('<https://example.com>', '_blank', commonFeatures);

  1. ブラウザ検出と分岐処理
function getBrowserSpecificFeatures() {
  const userAgent = navigator.userAgent.toLowerCase();
  let features = 'width=800,height=600,resizable=yes';

  if (userAgent.indexOf('firefox') > -1) {
    // Firefox向け追加オプション
    features += ',toolbar=no,location=no';
  } else if (userAgent.indexOf('edg') > -1 || userAgent.indexOf('chrome') > -1) {
    // Chrome/Edge向け追加オプション
    features += ',noopener=yes';
  } else if (userAgent.indexOf('safari') > -1 && userAgent.indexOf('chrome') === -1) {
    // Safari向け追加オプション(ChromeもuserAgentに'safari'を含むため除外)
    features += ',menubar=no';
  }

  return features;
}

// 使用例
const browserFeatures = getBrowserSpecificFeatures();
window.open('<https://example.com>', '_blank', browserFeatures);

機能検出

ブラウザの名前ではなく、特定の機能がサポートされているかをチェックする方法もあります。

function detectPopupCapabilities() {
  // テスト用の小さなウィンドウを開く
  const testWindow = window.open('', '_blank', 'width=1,height=1');
  const capabilities = {
    canOpenWindow: testWindow !== null && testWindow !== undefined,
    canAccessOpener: false,
    canCloseProgram: false
  };

  if (capabilities.canOpenWindow) {
    try {
      // opener関係のテスト
      capabilities.canAccessOpener = testWindow.opener === window;

      // プログラム的に閉じるテスト
      testWindow.close();
      capabilities.canCloseProgram = testWindow.closed;
    } catch (e) {
      console.log('機能テスト中にエラー:', e);
    }
  }

  return capabilities;
}

// 使用例
const popupCapabilities = detectPopupCapabilities();
if (popupCapabilities.canOpenWindow) {
  console.log('このブラウザではポップアップウィンドウが開けます');
}

開くURLにパラメータ(クエリストリング)を付けて渡す方法

別ウィンドウに情報を渡す一般的な方法は、URLのクエリパラメータを利用することです。しかし、パラメータに特殊文字や日本語が含まれる場合は、適切なエンコーディングが必要です。

基本的なクエリパラメータの追加:

function openWindowWithParams(baseUrl, params) {
  // URLオブジェクトを作成
  const url = new URL(baseUrl);

  // パラメータをURLSearchParamsに追加
  Object.keys(params).forEach(key => {
    url.searchParams.append(key, params[key]);
  });

  // ウィンドウを開く
  return window.open(url.toString(), '_blank');
}

// 使用例
const params = {
  id: 123,
  name: '田中太郎',
  category: '電子機器',
  fromApp: true
};

openWindowWithParams('<https://example.com/product>', params);
// <https://example.com/product?id=123&name=%E7%94%B0%E4%B8%AD%E5%A4%AA%E9%83%8E&category=%E9%9B%BB%E5%AD%90%E6%A9%9F%E5%99%A8&fromApp=true> が開かれる

この方法では、URLオブジェクトが自動的にパラメータを適切にエンコードしてくれます。特に日本語などの非ASCII文字は正しくエンコードする必要があります。

長いデータやJSON構造を渡す方法:

クエリパラメータでは長いデータやJSON構造を渡すのが難しい場合、一時的にセッションストレージやローカルストレージを利用する方法もあります。

function openWindowWithComplexData(url, key, data) {
  // データをJSON文字列に変換してセッションストレージに保存
  sessionStorage.setItem(key, JSON.stringify(data));

  // キーをクエリパラメータとして渡す
  const urlWithParam = new URL(url);
  urlWithParam.searchParams.append('dataKey', key);

  // ウィンドウを開く
  return window.open(urlWithParam.toString(), '_blank');
}

// 使用例
const complexData = {
  user: {
    id: 123,
    name: '山田花子',
    preferences: ['音楽', '映画', '読書'],
    history: [
      { date: '2023-04-01', action: 'login' },
      { date: '2023-04-02', action: 'purchase' }
    ]
  },
  products: [
    { id: 1, name: 'スマートフォン', price: 50000 },
    { id: 2, name: 'ヘッドフォン', price: 15000 }
  ]
};

openWindowWithComplexData('<https://example.com/dashboard>', 'userComplexData', complexData);

子ウィンドウ側では、以下のようにデータを取得します:

// 子ウィンドウ側のコード
window.addEventListener('DOMContentLoaded', function() {
  // URLからキーを取得
  const urlParams = new URLSearchParams(window.location.search);
  const dataKey = urlParams.get('dataKey');

  if (dataKey) {
    // セッションストレージからデータを取得
    const dataString = sessionStorage.getItem(dataKey);
    if (dataString) {
      try {
        const data = JSON.parse(dataString);
        console.log('親ウィンドウから受け取ったデータ:', data);

        // データを使った処理
        displayUserInfo(data.user);
        showProductList(data.products);

        // データを使用したら削除(オプション)
        sessionStorage.removeItem(dataKey);
      } catch (e) {
        console.error('データの解析に失敗しました:', e);
      }
    }
  }
});

安全なデータ受け渡し:

機密性の高いデータを渡す場合は、以下の点に注意が必要です:

  1. URLパラメータはブラウザ履歴に残るため、機密情報の受け渡しには不向き
  2. セッションストレージは同一オリジンのみアクセス可能だが、XSSなどの攻撃に注意
  3. 必要に応じてデータを暗号化するなど、追加のセキュリティ対策を検討
// データの暗号化(簡易的な例)
function encryptData(data, key) {
  // 実際のアプリケーションでは、より強力な暗号化アルゴリズムを使用すべき
  const encryptedData = btoa(JSON.stringify(data) + key);
  return encryptedData;
}

// データの復号
function decryptData(encryptedData, key) {
  try {
    const decoded = atob(encryptedData);
    // keyを使って検証
    if (decoded.endsWith(key)) {
      return JSON.parse(decoded.substring(0, decoded.length - key.length));
    }
    return null;
  } catch (e) {
    console.error('復号化に失敗:', e);
    return null;
  }
}

// 一時的なキーを生成
const tempKey = Math.random().toString(36).substring(2, 15);

// 暗号化してデータを渡す
const encryptedData = encryptData(sensitiveData, tempKey);
const newWindow = window.open('<https://example.com/secure?data=>' + encodeURIComponent(encryptedData), '_blank');

以上のように、JavaScriptで別ウィンドウを開く際には、ポップアップブロック対策、ブラウザ間の互換性、データの受け渡しなど、様々な注意点があります。これらを適切に理解し対処することで、よりスムーズなユーザー体験を提供できるでしょう。特にセキュリティ面での配慮は欠かさず、ユーザーのデータを保護する実装を心がけることが重要です。

【コピペで使える】別ウインドウを開くJavaScriptサンプルコード集

実際の開発シーンですぐに活用できる別ウィンドウを開くためのJavaScriptサンプルコードを集めました。初心者から上級者まで、さまざまなニーズに対応できるコード例を「コピペで使える」形式で提供します。必要に応じてカスタマイズして、ぜひご活用ください。

基本的な別ウィンドウの開き方コード例

まずは最も基本的な別ウィンドウを開くコード例から見ていきましょう。これらは単純ながらも、多くのケースで十分な機能を提供します。

1. シンプルな別ウィンドウを開く

// 最もシンプルな書き方
function openBasicWindow() {
  window.open('<https://example.com>', '_blank');
}

2. 名前付きウィンドウを開く

// 同じ名前を指定すると、既存のウィンドウが再利用される
function openNamedWindow() {
  window.open('<https://example.com>', 'myWindowName');
}

3. エラーハンドリング付きの基本的なウィンドウを開く

// ポップアップブロックなどの検出付き
function openWindowWithErrorHandling() {
  try {
    const newWindow = window.open('<https://example.com>', '_blank');

    if (!newWindow || newWindow.closed || typeof newWindow.closed === 'undefined') {
      alert('ポップアップがブロックされました。このサイトのポップアップを許可してください。');
      return null;
    }

    return newWindow;
  } catch (e) {
    console.error('ウィンドウを開く際にエラーが発生しました:', e);
    alert('ウィンドウを開けませんでした。');
    return null;
  }
}

4. 遅延して開く

// ページ読み込み後2秒経ってから開く
function openWindowWithDelay() {
  setTimeout(() => {
    window.open('<https://example.com>', '_blank');
  }, 2000); // 2000ミリ秒 = 2秒
}

5. 条件付きで開く

// ユーザーの確認後に開く
function openWindowWithConfirmation() {
  if (confirm('新しいウィンドウを開きますか?')) {
    window.open('<https://example.com>', '_blank');
  }
}

サイズ・位置・オプションを指定して開く応用コード例

より細かい制御が必要な場合のコード例です。ウィンドウのサイズや位置、UI要素の表示・非表示を指定できます。

1. サイズと位置を指定したウィンドウを開く

// 幅800px、高さ600pxのウィンドウを開く
function openWindowWithSize() {
  window.open('<https://example.com>', '_blank', 'width=800,height=600');
}

2. 画面中央に配置されたウィンドウを開く

// 画面中央に配置されたウィンドウを開く
function openCenteredWindow(url, winName, w, h) {
  // スクリーンの中心座標を計算
  const left = (screen.width - w) / 2;
  const top = (screen.height - h) / 2;

  // 位置とサイズを指定してウィンドウを開く
  const win = window.open(
    url,
    winName,
    `width=${w},height=${h},top=${top},left=${left}`
  );

  // 開いたウィンドウにフォーカスを当てる
  if (win) {
    win.focus();
  }

  return win;
}

// 使用例
openCenteredWindow('<https://example.com>', '_blank', 800, 600);

3. 最小限のUIで開く(モーダル風ウィンドウ)

// メニューバーやツールバーなしでシンプルなウィンドウを開く
function openMinimalWindow(url) {
  const features = 'width=800,height=600,toolbar=no,location=no,directories=no,status=no,menubar=no';
  return window.open(url, '_blank', features);
}

4. カスタムオプションをすべて指定したウィンドウを開く

// 細かくカスタマイズされたウィンドウを開く
function openCustomWindow(url, options = {}) {
  // デフォルトのオプション
  const defaultOptions = {
    width: 800,
    height: 600,
    left: 0,
    top: 0,
    toolbar: 'no',
    location: 'no',
    directories: 'no',
    status: 'no',
    menubar: 'no',
    scrollbars: 'yes',
    resizable: 'yes',
    centerscreen: 'yes',
    chrome: 'yes'
  };

  // ユーザー指定のオプションで上書き
  const mergedOptions = { ...defaultOptions, ...options };

  // オプションを文字列に変換
  const features = Object.entries(mergedOptions)
    .map(([key, value]) => `${key}=${value}`)
    .join(',');

  return window.open(url, '_blank', features);
}

// 使用例
openCustomWindow('<https://example.com>', {
  width: 1024,
  height: 768,
  resizable: 'yes'
});

5. レスポンシブなウィンドウを開く(画面サイズに基づく)

// 画面サイズに応じてウィンドウサイズを調整
function openResponsiveWindow(url) {
  // 画面サイズを取得
  const screenW = window.screen.width;
  const screenH = window.screen.height;

  let width, height;

  // 画面サイズに応じてウィンドウサイズを設定
  if (screenW >= 1920) {
    width = 1280;
    height = 800;
  } else if (screenW >= 1280) {
    width = 1024;
    height = 700;
  } else {
    width = Math.round(screenW * 0.8);
    height = Math.round(screenH * 0.8);
  }

  // 中央に配置
  const left = (screenW - width) / 2;
  const top = (screenH - height) / 2;

  return window.open(
    url,
    '_blank',
    `width=${width},height=${height},top=${top},left=${left},resizable=yes,scrollbars=yes`
  );
}

ボタンクリックで別ウィンドウを開くイベントリスナーの設置方法

実際のWebページでは、ボタンクリックなどのユーザーアクションに応じて別ウィンドウを開くことが一般的です。以下はそのためのさまざまなコード例です。

1. 基本的なクリックイベントリスナー

// HTML: <button id="openWindowBtn">ウィンドウを開く</button>

// JavaScriptでイベントリスナーを追加
document.addEventListener('DOMContentLoaded', function() {
  const button = document.getElementById('openWindowBtn');

  if (button) {
    button.addEventListener('click', function() {
      window.open('<https://example.com>', '_blank');
    });
  }
});

2. 複数のボタンに対応するイベントリスナー

// HTML:
// <button class="popup-link" data-url="<https://example.com>">サイト1</button>
// <button class="popup-link" data-url="<https://example.org>">サイト2</button>
// <button class="popup-link" data-url="<https://example.net>">サイト3</button>

// すべての .popup-link ボタンにイベントリスナーを設定
document.addEventListener('DOMContentLoaded', function() {
  const buttons = document.querySelectorAll('.popup-link');

  buttons.forEach(button => {
    button.addEventListener('click', function() {
      const url = this.getAttribute('data-url');
      if (url) {
        window.open(url, '_blank');
      }
    });
  });
});

3. 動的に生成されたボタンでも機能するイベントデリゲーション

// HTML:
// <div id="buttonContainer">
//   <button class="popup-link" data-url="<https://example.com>">サイト1</button>
//   <!-- 後から動的に追加されるボタンも対応可能 -->
// </div>

// イベントデリゲーションを使用してクリックを検知
document.addEventListener('DOMContentLoaded', function() {
  const container = document.getElementById('buttonContainer');

  if (container) {
    container.addEventListener('click', function(e) {
      // クリックされた要素またはその親要素が .popup-link クラスを持つか検証
      const button = e.target.closest('.popup-link');

      if (button) {
        const url = button.getAttribute('data-url');
        if (url) {
          window.open(url, '_blank');
        }
      }
    });
  }

  // 動的にボタンを追加する例
  function addNewButton(url, text) {
    const newButton = document.createElement('button');
    newButton.className = 'popup-link';
    newButton.setAttribute('data-url', url);
    newButton.textContent = text;
    container.appendChild(newButton);
  }

  // 使用例
  // addNewButton('<https://example.org>', '新しいサイト');
});

4. リンク(a要素)のデフォルト動作をカスタマイズ

// HTML:
// <a href="<https://example.com>" class="custom-popup" data-width="800" data-height="600">サイトを開く</a>

// リンクのデフォルト動作をカスタムポップアップに変更
document.addEventListener('DOMContentLoaded', function() {
  const links = document.querySelectorAll('a.custom-popup');

  links.forEach(link => {
    link.addEventListener('click', function(e) {
      e.preventDefault(); // デフォルトのリンク動作を防止

      const url = this.href;
      const width = this.getAttribute('data-width') || 800;
      const height = this.getAttribute('data-height') || 600;

      // 中央に配置
      const left = (screen.width - width) / 2;
      const top = (screen.height - height) / 2;

      window.open(
        url,
        '_blank',
        `width=${width},height=${height},top=${top},left=${left}`
      );
    });
  });
});

5. フォーム送信を別ウィンドウで行う

// HTML:
// <form id="externalForm" action="<https://example.com/submit>" method="post">
//   <input type="text" name="name" placeholder="名前">
//   <button type="submit">送信</button>
// </form>

// フォーム送信を別ウィンドウで行う
document.addEventListener('DOMContentLoaded', function() {
  const form = document.getElementById('externalForm');

  if (form) {
    form.addEventListener('submit', function(e) {
      e.preventDefault(); // フォームのデフォルト送信を防止

      // 新しいウィンドウを開く
      const newWindow = window.open('', 'submitWindow', 'width=800,height=600');

      if (newWindow) {
        // フォームのターゲットを新しいウィンドウに設定
        form.target = 'submitWindow';
        // フォームを送信
        form.submit();
      } else {
        alert('ポップアップがブロックされました。設定を確認してください。');
        // 通常の送信にフォールバック
        form.target = '_self';
        form.submit();
      }
    });
  }
});

応用例:実用的なシナリオ別サンプル

より実践的なシナリオに対応したコード例です。実際のプロジェクトですぐに活用できます。

1. プリント用ウィンドウを開き、自動的に印刷ダイアログを表示

// HTML: <button id="printBtn">この内容を印刷</button>

document.getElementById('printBtn').addEventListener('click', function() {
  // 印刷用のコンテンツを準備
  const printContent = `
    <!DOCTYPE html>
    <html>
    <head>
      <title>印刷ページ</title>
      <style>
        body { font-family: Arial, sans-serif; }
        .print-header { text-align: center; margin-bottom: 20px; }
        .print-content { line-height: 1.5; }
        @media print {
          .no-print { display: none; }
        }
      </style>
    </head>
    <body>
      <div class="print-header">
        <h1>印刷用ドキュメント</h1>
        <p>作成日: ${new Date().toLocaleDateString()}</p>
      </div>
      <div class="print-content">
        ${document.getElementById('contentToPrint')?.innerHTML || 'コンテンツが見つかりません'}
      </div>
      <div class="no-print">
        <button onclick="window.print()">印刷</button>
        <button onclick="window.close()">閉じる</button>
      </div>
      <script>
        // 読み込み完了後に印刷ダイアログを自動表示
        window.onload = function() {
          setTimeout(function() {
            window.print();
          }, 500);
        };
      </script>
    </body>
    </html>
  `;

  // 新しいウィンドウを開く
  const printWindow = window.open('', '_blank', 'width=800,height=600');

  if (printWindow) {
    printWindow.document.open();
    printWindow.document.write(printContent);
    printWindow.document.close();
  } else {
    alert('印刷用ウィンドウを開けませんでした。ポップアップブロックを確認してください。');
  }
});

2. PDFファイルを別ウィンドウで開く(埋め込みビューア付き)

// HTML: <button id="viewPdfBtn" data-pdf-url="/path/to/document.pdf">PDFを表示</button>

document.getElementById('viewPdfBtn').addEventListener('click', function() {
  const pdfUrl = this.getAttribute('data-pdf-url');
  if (!pdfUrl) return;

  // PDFを埋め込んだHTMLを作成
  const pdfViewerHtml = `
    <!DOCTYPE html>
    <html>
    <head>
      <title>PDF表示</title>
      <style>
        body, html { margin: 0; padding: 0; height: 100%; overflow: hidden; }
        .pdf-container { width: 100%; height: 100%; }
      </style>
    </head>
    <body>
      <div class="pdf-container">
        <object data="${pdfUrl}" type="application/pdf" width="100%" height="100%">
          <p>ご利用のブラウザはPDFの埋め込み表示に対応していません。
          <a href="${pdfUrl}" target="_blank">PDFをダウンロード</a>してください。</p>
        </object>
      </div>
    </body>
    </html>
  `;

  // 新しいウィンドウでPDFビューアを開く
  const pdfWindow = window.open('', '_blank', 'width=800,height=600,resizable=yes');

  if (pdfWindow) {
    pdfWindow.document.open();
    pdfWindow.document.write(pdfViewerHtml);
    pdfWindow.document.close();
  }
});

3. 親子ウィンドウ間でデータをやり取りする高度な例

// 親ウィンドウ側のコード
let childWindow = null;

// データを送信する関数
function sendDataToChild(data) {
  if (childWindow && !childWindow.closed) {
    // 子ウィンドウがすでに開いている場合
    childWindow.postMessage(data, '*');
  } else {
    // 子ウィンドウを新規に開く
    const url = 'child.html' + (data ? `?initialData=${encodeURIComponent(JSON.stringify(data))}` : '');
    childWindow = window.open(url, 'childWindow', 'width=600,height=400');

    // windowが作成されたかチェック
    if (!childWindow || childWindow.closed || typeof childWindow.closed === 'undefined') {
      alert('ポップアップウィンドウを開けませんでした。');
      return null;
    }
  }

  return childWindow;
}

// 子ウィンドウからのメッセージを受信
window.addEventListener('message', function(event) {
  // オリジン検証などのセキュリティチェックを行うべき
  console.log('子ウィンドウからデータを受信:', event.data);

  // 受信したデータを処理
  document.getElementById('receivedData').textContent = JSON.stringify(event.data, null, 2);
});

// 送信ボタンのイベントリスナー
document.getElementById('sendToChildBtn').addEventListener('click', function() {
  const dataToSend = {
    message: document.getElementById('messageInput').value || 'こんにちは!',
    timestamp: new Date().toISOString(),
    sender: 'parent'
  };

  sendDataToChild(dataToSend);
});
// 子ウィンドウ側のコード (child.html)
document.addEventListener('DOMContentLoaded', function() {
  // URLからデータを取得
  const urlParams = new URLSearchParams(window.location.search);
  const initialDataParam = urlParams.get('initialData');

  if (initialDataParam) {
    try {
      const initialData = JSON.parse(decodeURIComponent(initialDataParam));
      displayReceivedData(initialData);
    } catch (e) {
      console.error('初期データの解析に失敗:', e);
    }
  }

  // 親ウィンドウからのメッセージを受信
  window.addEventListener('message', function(event) {
    // オリジン検証などのセキュリティチェックを行うべき
    console.log('親ウィンドウからデータを受信:', event.data);
    displayReceivedData(event.data);
  });

  // 受信したデータを表示
  function displayReceivedData(data) {
    document.getElementById('receivedData').textContent = JSON.stringify(data, null, 2);
  }

  // 親ウィンドウにメッセージを送信
  document.getElementById('replyBtn').addEventListener('click', function() {
    const replyData = {
      message: document.getElementById('replyInput').value || '返信です!',
      timestamp: new Date().toISOString(),
      sender: 'child'
    };

    if (window.opener && !window.opener.closed) {
      window.opener.postMessage(replyData, '*');
      console.log('親ウィンドウにデータを送信:', replyData);
    }
  });
});

4. ギャラリー画像を大きな別ウィンドウで表示

// HTML:
// <div class="gallery">
//   <img src="image1-thumb.jpg" data-full="image1-full.jpg" class="gallery-item" alt="画像1">
//   <img src="image2-thumb.jpg" data-full="image2-full.jpg" class="gallery-item" alt="画像2">
//   <!-- 他の画像 -->
// </div>

document.addEventListener('DOMContentLoaded', function() {
  // ギャラリー内の全画像にイベントリスナーを設定
  const galleryItems = document.querySelectorAll('.gallery-item');

  galleryItems.forEach(item => {
    item.addEventListener('click', function() {
      const fullSizeUrl = this.getAttribute('data-full');
      const altText = this.getAttribute('alt') || '画像';

      if (fullSizeUrl) {
        openImageViewer(fullSizeUrl, altText);
      }
    });
  });

  // 画像ビューアウィンドウを開く関数
  function openImageViewer(imageUrl, altText) {
    const viewerHtml = `
      <!DOCTYPE html>
      <html>
      <head>
        <title>${altText}</title>
        <style>
          body, html { margin: 0; padding: 0; height: 100%; background: #000; display: flex; align-items: center; justify-content: center; }
          img { max-width: 100%; max-height: 100%; object-fit: contain; }
          .close-btn { position: absolute; top: 10px; right: 10px; color: white; background: rgba(0,0,0,0.6); border: none; padding: 5px 10px; cursor: pointer; }
        </style>
      </head>
      <body>
        <button class="close-btn" onclick="window.close()">閉じる</button>
        <img src="${imageUrl}" alt="${altText}" />
      </body>
      </html>
    `;

    // 画面サイズを取得
    const screenW = window.screen.width;
    const screenH = window.screen.height;

    // 大きめのウィンドウサイズを設定(画面の80%)
    const width = Math.round(screenW * 0.8);
    const height = Math.round(screenH * 0.8);

    // 中央に配置
    const left = (screenW - width) / 2;
    const top = (screenH - height) / 2;

    // ウィンドウを開く
    const imageWindow = window.open('', '_blank', `width=${width},height=${height},top=${top},left=${left}`);

    if (imageWindow) {
      imageWindow.document.open();
      imageWindow.document.write(viewerHtml);
      imageWindow.document.close();
    }
  }
});

5. ログイン・認証ウィンドウの実装(OAuth風)

// OAuth風の認証ウィンドウを開き、認証完了後のコールバックを処理
function openAuthWindow(authUrl, clientId, redirectUri) {
  // 認証URLを作成
  const fullAuthUrl = `${authUrl}?client_id=${encodeURIComponent(clientId)}&redirect_uri=${encodeURIComponent(redirectUri)}&response_type=code&scope=read`;

  // ウィンドウサイズを設定
  const width = 600;
  const height = 700;
  const left = (screen.width - width) / 2;
  const top = (screen.height - height) / 2;

  // 認証ウィンドウを開く
  const authWindow = window.open(
    fullAuthUrl,
    'authWindow',
    `width=${width},height=${height},top=${top},left=${left},toolbar=no,location=yes,directories=no,status=yes,menubar=no,resizable=yes,scrollbars=yes`
  );

  // ウィンドウが開けなかった場合
  if (!authWindow) {
    alert('認証ウィンドウを開けませんでした。ポップアップブロックを確認してください。');
    return;
  }

  // メッセージイベントを設定(redirectUri側で postMessage を呼び出す必要あり)
  window.addEventListener('message', function authMessageListener(event) {
    // リダイレクト先のオリジンからのメッセージのみ受け入れる
    const redirectOrigin = new URL(redirectUri).origin;
    if (event.origin !== redirectOrigin) return;

    // 認証コードを取得
    const { code, state, error } = event.data;

    // 認証ウィンドウを閉じる
    if (authWindow && !authWindow.closed) {
      authWindow.close();
    }

    // イベントリスナーを削除
    window.removeEventListener('message', authMessageListener);

    if (error) {
      console.error('認証エラー:', error);
      alert('認証に失敗しました: ' + error);
      return;
    }

    if (code) {
      console.log('認証コード取得:', code);
      // 認証コードを使ってトークンを取得するなどの処理
      exchangeCodeForToken(code);
    }
  });

  // 認証コードからトークンを取得する関数(実際の実装はAPIによる)
  function exchangeCodeForToken(code) {
    console.log('取得したコードでトークンを要求します:', code);
    // ここで実際のAPIリクエストを行う
    // fetch('/token', { method: 'POST', body: JSON.stringify({ code }) }) など
  }
}

// 使用例
document.getElementById('loginBtn').addEventListener('click', function() {
  openAuthWindow(
    '<https://auth-provider.com/authorize>',
    'your-client-id',
    '<https://your-app.com/callback>'
  );
});

以上が「コピペで使える」別ウィンドウを開くためのJavaScriptサンプルコード集です。基本的な使い方から高度なユースケースまで幅広くカバーしています。実際の開発では、セキュリティやユーザー体験に配慮しながら、これらのコードを必要に応じてカスタマイズしてご活用ください。

JavaScriptでブラウザバックを正確に判定する方法|よくある失敗と対処法もセットで解説
JavaScriptでブラウザバックを判定する方法を基礎から解説。popstate・pageshowイベントの違いや実装例、戻るボタンによる誤操作の防止方法、SPA(React・Vue・Next.js)やSafari特有の挙動への対応、Google Analyticsとの連携方法まで幅広く紹介しています。

まとめ

この記事では、JavaScriptを使って別ウィンドウを開く方法について詳しく解説してきました。特に重要なポイントをまとめると以下のようになります:

  • window.open()の基本構文:URL、ウィンドウ名、オプションを指定して別ウィンドウを開くことができます
  • 表示オプションの活用:width、height、top、leftなどのパラメータで、サイズや位置を細かく制御できます
  • 戻り値の活用window.open()の戻り値(WindowProxyオブジェクト)を変数に格納することで、開いたウィンドウの操作が可能になります
  • ポップアップブロッカー対策:ユーザーのクリックイベントに紐づけて実装するなど、適切な対応が必要です

別ウィンドウ機能は、メインコンテンツを邪魔せずに追加情報を表示したり、特定の機能を分離したりするのに非常に便利です。しかし、ユーザー体験を考慮して使用する必要があります。むやみに別ウィンドウを開くと、ユーザーを混乱させる可能性があるため、本当に必要な場合にのみ使用しましょう。

また、ブラウザ間の互換性の問題や、モバイルデバイスでの動作の違いにも注意が必要です。サンプルコードを自分のプロジェクトに活用する際は、各主要ブラウザでのテストを忘れずに行ってください。

今回紹介したテクニックを応用すれば、よりインタラクティブで使いやすいウェブアプリケーションの開発が可能になります。特に初めて実装する方は、基本的な使い方から始めて、徐々に応用的な機能を追加していくことをおすすめします。

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