ブラウザを閉じるときに、親画面が開いた子画面（サブウィンドウ）を閉じる

親画面から子画面を開いたとき、親画面を閉じられると子画面が残ってしまいます。
この投稿では、親画面が閉じられるときに開いた子画面を閉じる処理を行うというものです。
サーバには、django(python)を使います。

親画面を閉じられたとき、子、孫画面を閉じる

![image.png](https://qiita-image-store.s3.amazonaws.com/0/246741/38a03254-ad89-14d0-c8aa-92399e572cb1.png)

###1.環境

特に環境は関係ありませんが、一応掲載しておきます。

| カテゴリ       | バージョンなど       |
|:-----------------|------------------:|
| os               |windows 10 home 64bit | 
| python           |            3.6.5 |
| django             |              2.0.7|
| プロジェクト         | myproject|

###2.javascript

今回のメインとなるjavascriptです。

```static\js\subwin.js
  var subWindows={};
  // CLOSE
  function CloseWindow(subWindow) {
      if (typeof subWindow != "undefined") {
          subWindow.close();
      }
  }
  function OpenSubWin(elem) {
    if (typeof subWindows[elem.target] != "undefined") {
      CloseWindow(subWindows[elem.target]);
    }
    subWindows[elem.target] = window.open($(elem).attr('href'), $(elem).text(), "width=1300,height=700,scrollbars=yes");
  }
  // アンロード時にサブ画面を閉じる
  window.onunload = function() {
    Object.keys(subWindows).forEach(function(key) {
      CloseWindow(subWindows[key]);
    });
  }
```

subWindowsに、自身が開いたwindowオブジェクトを格納していきます。
window.onunloadで、開いたwindowオブジェクトをすべてcloseするという仕様です。


###3.Djangoでサンプルアプリを作成する

####(1)urls.py

index=親、 childwin=子、grandsonwin=孫になります。

```urls.py
from django.urls import path
from . import views

app_name = 'subwin'
urlpatterns = [
    path('', views.index, name='index'),
    path('childwin/', views.childwin, name='childwin'),
    path('grandsonwin/', views.grandsonwin, name='grandsonwin'),
]
```

####(2)views.py

htmlを返すだけの簡単なものです。

```views.py
from django.shortcuts import render

def index(request):
    return render(request, 'subwin/parent.html')

def childwin(request):
    return render(request, 'subwin/childwin.html')

def grandsonwin(request):
    return render(request, 'subwin/grandson.html')
```

####(3)html

#####1) parent.html

```parent.html
{% extends "commons/base.html" %}

{% load static %}

{% block title %}
{% endblock title %}

{% block links %}
<script src="{% static 'js/subwin.js' %}"></script>
{% endblock links %}

{% block headertitle %}
サブウィンドウ　サンプル（親画面）
{% endblock %}

{% block content %}
<a href="{% url 'subwin:childwin' %}" target="child1" onclick="OpenSubWin(this);return false;">子画面１</a>
<br/>
<a href="{% url 'subwin:childwin' %}" target="child2" onclick="OpenSubWin(this);return false;">子画面２く</a>
<br/>
<button onclick="console.log(subWindows['child']);return false;">子画面情報</button>
{% endblock %}
```

#####2) childwin.html

```childwin.html
{% extends "commons/base.html" %}

{% load static %}

{% block title %}
{% endblock title %}

{% block links %}
<script src="{% static 'js/subwin.js' %}"></script>
{% endblock links %}

{% block headertitle %}
サブウィンドウ　サンプル（子画面）
{% endblock %}

{% block content %}

<a href="{% url 'subwin:grandsonwin' %}" target="grandson" onclick="OpenSubWin(this);return false;">孫画面を開く</a>

<br/>
<button onclick="window.close();">閉じる</button>

{% endblock %}
```

#####3) grandson.html

```grandson.html
{% extends "commons/base.html" %}

{% load static %}

{% block title %}
{% endblock title %}

{% block links %}
<script src="{% static 'js/subwin.js' %}"></script>
{% endblock links %}

{% block headertitle %}
サブウィンドウ　サンプル（孫画面）
{% endblock %}

{% block content %}
<button onclick="window.close();">閉じる</button>
{% endblock %}
```

実行して子画面、孫画面を表示した状態で親画面を閉じると、子、孫画面も閉じると思います。

以上