🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

2回答

3073閲覧

window.open実行時にウィンドウが閉じてしまう

circular2016

総合スコア52

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2019/12/24 00:59

window.open()実行時、ウィンドウが開くどころか逆に閉じてしまう事象になってしまっており、ご助言を頂きたく質問させて頂きます。

前提・実現したいこと

某ユーザIDの詳細情報表示画面がある。

①そのユーザIDに、old_idが存在した場合、そのold_idの詳細情報を別ウィンドウで表示させる。
②そのold_idにさらにold_idがあった場合、さらに新しく別ウィンドウで表示させる。
③以下、old_idが存在しなくなるまで(理論上は)無限に別ウィンドウを開き続ける。

発生している問題・エラーメッセージ

上記の②でエラーになります。

上記①までは正常に機能するのですが、そこからold_id情報を参照しようと別ウィンドウを開こうとすると、別ウィンドウが開かないばかりか、今開いているウィンドウが閉じてしまいます。

エラーメッセージ

特にありません。
(開発者ツールごと終了するため、コンソールも確認できない)

該当のソースコード

javascript

1 2var win = window.open(u, name, options); 3

uは、”http://localhost:8080/hogehoge?idParam=idValue”

nameは、”subwin”
で、別ウィンドウは全てこの値で無限に開こうとしています。

試したこと

上記②の時の
nameを”_blank”に変えてみたところ、
新規ウィンドウは開きませんでしたが、今あるウィンドウは閉じませんでした。

また、開発者ツールの変数LIVE変換で、nameを変えてみたところ、一応上記②③が実現できました。

しかし、何故そうなるのか、原因がわかりません。

補足情報(FW/ツールのバージョンなど)

ブラウザはchrome、IEともに上記挙動です。

よろしくお願い致します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

coco_bauer

2019/12/24 01:15

なにをしようとしているのか、よくわかりません。 「そのユーザIDに、old_idが存在」とか「そのold_idにさらにold_idがあった」で出てくるユーザIDとかold_idというのは何ですか? 該当のソースコードには、old_idもユーザIDも出てきませんが、なにか関係していますか?
circular2016

2019/12/24 01:46

失礼致しました。 まず、現状のシステムにつきまして、 ユーザの情報検索画面→一覧画面→個別の詳細画面、 と遷移するつくりになっております。 idがユーザ情報の主キーになっており、これでSELECTしてきます。 ただ、ユーザ情報は、以前の登録を引用して登録することができ、 引用登録した場合は、引用元がold_idとしてレコードに登録されるのです。 (理論上は無限に引用登録をすることができます。) 現在の機能では、何のidから引用登録をしたのか、つまり、old_idの詳細情報を画面からは確認することができません。 これを参照できるようにしたいと考えております。 方法として、既存の詳細画面の下に「引用申請参照ボタン」を追加し、 押下時に、別ウィンドウでold_idについての情報を表示させたいです。 その別ウィンドウで開かれたユーザ情報(old_id情報)が、さらに前のid情報から引用されたものであれば、 さらに参照ボタンを表示し、別ウィンドウで開けるようにしたいです。 これが無限に続きます。 ソースにold_idがございませんでしたが、 第一引数の最後、"idParam=idValue"にold_idが指定されることになります。 説明不足で申し訳ありません。よろしくお願い致します。
guest

回答2

0

また、開発者ツールの変数LIVE変換で、nameを変えてみたところ、一応上記②③が実現できました。

しかし、何故そうなるのか、原因がわかりません。

MDN からの抜粋ですが、window.open() の第二引数を指定するとき、次の挙動になります。

name の名前を持っているウィンドウがすでに存在する場合は、新しいウィンドウが開かれる代わりに、url がその存在するウィンドウにロードされます。

無限に新しいウィンドウを開きたい場合、同じnameを指定することはできないことを意味します。

投稿2019/12/24 01:07

thyda.eiqau

総合スコア2982

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

circular2016

2019/12/24 09:11

ありがとうございます! 見落としておりました。 「nameを”_blank”に変えてみたところ、新規ウィンドウは開きませんでした」 と質問欄で書いていましたが、 _blankに変更するファイルを誤っておりました。。 正しいファイルで、name="_blank"と変えたところ、 複数ウィンドウが表示できるようになりました。
guest

0

ベストアンサー

nameは、”subwin” で、別ウィンドウは全てこの値で無限に開こうとしています。

閉じる原因ですね。

window.open() を使う場合、利用者の利便を考えたイベントハンドラを設計することが重要。

基本:

javascript

1const subwins = {}; 2const openSubWindow = ( url, name ) => { 3 if(!subwins[name]) { 4 // サブウィンドウのインスタンスを管理 5 subwins[name] = window.open( url, name ); 6 7 // 制御用イベントハンドラは必ず設計する。 8 9 // 呼び出し元が閉じようとしたら、サブウィンドウを強制的に閉じる実装例 10 window.addEventListener("beforeunload", function(){ 11 subwins[name].close(); 12 }); 13 } 14}

①そのユーザIDに、old_idが存在した場合、そのold_idの詳細情報を別ウィンドウで表示させる。

②そのold_idにさらにold_idがあった場合、さらに新しく別ウィンドウで表示させる。
③以下、old_idが存在しなくなるまで(理論上は)無限に別ウィンドウを開き続ける。

仕様上、②を実現するには、別名を与える必要があります。
第二引数に与える name はsubwinIdなどに置き換えて自動生成して管理し、共通するイベントハンドラもアタッチするよう、(class ブロックを用いるなどの)オブジェクトとして設計するのが望ましいです。

nameを”_blank”に変えてみたところ

安易に "_blank" を使う前に、開いた「サブウィンドウをどのように制御すべきか」を考えてください。

※ご質問が「単純に開けばOK」という内容ではなさそうでしたので、方法論を述べさせていただきました。

投稿2019/12/24 01:35

編集2019/12/24 02:38
AkitoshiManabe

総合スコア5434

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

circular2016

2019/12/24 09:17

細かくありがとうございます! 経験が浅いのでよくわかっていない部分が多く、例えばnameをMath.random()を使ってid生成する方法もあるかと思いましたが、name="_blank"にして期待する動作になりましたので、 "_blank"にしてしまいました。 呼び出し元ウィンドウでwindow.closeした場合、 呼び出し先ウィンドウも閉じられる、という動きですが、 既存のモジュールとして、prototype.jsの Event.observeがありましたので、これを使い、 Event.observe(window, 'unload' , closeAllWindows); として、 閉じられることを確認致しました。
AkitoshiManabe

2019/12/24 12:17

prototype.js はビルトインオブジェクトの拡張が激しく酷評されています。とはいえ、便利な独自実装も多数ありますので、MITの示すとおり 作者情報を示して切り取っちゃうのは有りかもしれませんね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問