「画像でゴミ分類！」アプリ作成日誌day7～サイドバーのスライドメニュー化～

# はじめに
「画像でゴミ分類！」アプリ作成日誌7日目の今日はサイドバーのスマホ対応ということでHTML,CSS,JavaScriptをガッツリ書いて、横から出てくるスライドメニューを実装していく回です。


＜記事一覧＞

- [「画像でゴミ分類！」アプリ作成日誌day1～データセットの作成～](https://qiita.com/eycjur/items/7d8223b28758c7dfaaa0)
- [「画像でゴミ分類！」アプリ作成日誌day2～VGG16でFine-tuning～](https://qiita.com/eycjur/items/3e954cb70dc15f996c2d)
- [「画像でゴミ分類！」アプリ作成日誌day3～Djangoでwebアプリ化～](https://qiita.com/eycjur/items/9c618538177c82f7fdc3)
- [「画像でゴミ分類！」アプリ作成日誌day4～Bootstrapでフロントエンドを整える～](https://qiita.com/eycjur/items/7b58c28eb8b16e722b5d)
- [「画像でゴミ分類！」アプリ作成日誌day5～Bootstrapでフロントエンドを整える2～](https://qiita.com/eycjur/items/08808097acd625e00652)
- [「画像でゴミ分類！」アプリ作成日誌day6～ディレクトリ構成の修正～](https://qiita.com/eycjur/items/f436787c2d517af6cad6)
- [「画像でゴミ分類！」アプリ作成日誌day7～サイドバーのスライドメニュー化～](https://qiita.com/eycjur/items/009dca5866c3e9ad0dd6) ←イマココ
- [「画像でゴミ分類！」アプリ作成日誌day8～herokuデプロイ～](https://qiita.com/eycjur/items/ebfae5db5dd1cd8349ea)

# 前回までのあらすじ
前回までの記事では画像認識アプリを実装してDjangoに載せたうえで、Bootstrapを使ってフロントエンドを整えるところまでやりました。サイドバーに関してはスマホの際は非表示にするような設定にしていましたが、それでは味気ないのでボタンをタップしたら表示されるようにしたいと思います。

```django:garbage/templates/garbage/base.html
# トグル用のボタンの設置
		<button class="toggler d-md-none display-toggler-inline" type="button" id="toggler" onclick="Sidebar()">
			<i class="fas fa-bars fa-2x"></i>
		</button>
```
Font Awesomeを利用してアイコンを設置していきます。`d-md-none`というクラスを設定することで、画面が小さい時しか表示しないというのをBootstrapで制御しています。なお、Sidebar()は何もしない関数にしてあります。

次にボタンクリック時に表示されるサイドバーを作っていきます。

```django:garbage/templates/garbage/base.html
<body>
	<div id="side-bar" class="display-sidebar-none d-md-none">
		<div type=button id="close-button" class="mr-1" onclick="Sidebar()">
			×
		</div>
		<p role="button" class="mb-2 btn border-dark rounded-0 btn-secondary">外部リンク集</p>
		<a href="https://manage.delight-system.com/threeR/web/bunbetsu?menu=bunbetsu&jichitaiId=kashiwashi&areaId=22125&areaName=%2F&lang=ja&benriCateId=7&bunbetsuCateId=7&faqCateId=%2F&howToCateId=&search=%E3%83%9A%E3%83%83%E3%83%88%E3%83%9C%E3%83%88%E3%83%AB&dummy=" class="btn btn-default border-dark mb-1 rounded-0" role="button" target="_blank" rel="noopener noreferrer">分別検索</a>
		<a href="https://manage.delight-system.com/threeR/web/benri?menu=benri&jichitaiId=kashiwashi&areaId=22125&benriCateId=7&bunbetsuCateId=7&faqCateId=%2f&lang=ja" class="btn btn-default border-dark mb-1 rounded-0" role="button" target="_blank" rel="noopener noreferrer">ごみの分け方・出し方</a>
	</div>
```
これは、ほかの要素にかぶせて使うので、body直下に置いています。3~5行目で閉じるボタンを文字で直接実装しています。それ以降は中身なので、PC版の記述をそのまま利用しています。

そして、CSSは以下のようにすると、ほかの要素の上にかぶせて表示することができます。

```css:garbage/static/garbage/css/style.css
#side-bar{
	position: fixed;
	z-index: 1;
	height: 100vh;
	width: 250px;
	opacity: 0.9;
	background-color: white;
}

#close-button{
	float: right;
	font-size: 400%;
	font-weight: bold;
	height: 90px;
}
```
`position`で固定位置に表示できるようにし、`height,width`で大きさを指定します。また、`z-index`で前面に表示するようにしています。
閉じるボタンについてもいい感じになるようにしています。

# JavaScriptの実装
ここまでで基本的な形はできたので、JSで動きを実装していきます。
まず、JavaScriptで追加・削除するためのクラスを書いていきます。

```css:garbage/static/garbage/css/style.css
.display-sidebar-none{
	transition: all 0.5s;
	left: -250px;
}

.display-sidebar-inline{
	transition: all 0.5s;
	left: 0;
}

.display-toggler-none{
	transition: all 0.3s;
	opacity: 0;
}

.display-toggler-inline{
	transition: all 1.5s;
	opacity: 1.0;
}
```
やっていることとしては、上二つでsidebarの位置を動かします。こうすることであたかも左から出てきたかのような効果を演出できます。
また、下二つでtoggleボタンの表示非表示を切り替えています。fadeのようなことをしたかったので、透明度を変化させます。
それぞれ、transitionを設定することで、クラスを付与した際に起こる変化をゆっくりにすることができ、視覚的になじみやすく表現することができます。

それではいよいよJavaScriptの実装です。

```django:garbage/templates/garbage/base.html
	<script>
		function Sidebar(){
			document.getElementById("side-bar").classList.toggle("display-sidebar-none");
			document.getElementById("side-bar").classList.toggle("display-sidebar-inline");
			document.getElementById("toggler").classList.toggle("display-toggler-none");
			document.getElementById("toggler").classList.toggle("display-toggler-inline");
		}
	</script>
```
classList.toggleでクラスがあれば削除し、なければ追加ということを一括で処理しています。

実際に実装できたものは以下のような挙動になります。めっちゃちゃんと動いてる!!!
![サイドバー.gif](https://github.com/eycjur/garbage/blob/master/qiita_image/%E3%82%B5%E3%82%A4%E3%83%89%E3%83%90%E3%83%BC.gif?raw=True)

＜記事一覧＞

- [「画像でゴミ分類！」アプリ作成日誌day1～データセットの作成～](https://qiita.com/eycjur/items/7d8223b28758c7dfaaa0)
- [「画像でゴミ分類！」アプリ作成日誌day2～VGG16でFine-tuning～](https://qiita.com/eycjur/items/3e954cb70dc15f996c2d)
- [「画像でゴミ分類！」アプリ作成日誌day3～Djangoでwebアプリ化～](https://qiita.com/eycjur/items/9c618538177c82f7fdc3)
- [「画像でゴミ分類！」アプリ作成日誌day4～Bootstrapでフロントエンドを整える～](https://qiita.com/eycjur/items/7b58c28eb8b16e722b5d)
- [「画像でゴミ分類！」アプリ作成日誌day5～Bootstrapでフロントエンドを整える2～](https://qiita.com/eycjur/items/08808097acd625e00652)
- [「画像でゴミ分類！」アプリ作成日誌day6～ディレクトリ構成の修正～](https://qiita.com/eycjur/items/f436787c2d517af6cad6)
- [「画像でゴミ分類！」アプリ作成日誌day7～サイドバーのスライドメニュー化～](https://qiita.com/eycjur/items/009dca5866c3e9ad0dd6) ←イマココ
- [「画像でゴミ分類！」アプリ作成日誌day8～herokuデプロイ～](https://qiita.com/eycjur/items/ebfae5db5dd1cd8349ea)