JavaScriptで簡単なダークモード切替機能を作る

# 概要・目的
　こんにちは、プログラミング初心者です。
　今回はHTML＆CSSとJavaScriptのDOM操作だけで簡単に実装できる、夜目に優しいダークモードを搭載する方法を紹介したいと思います。

## ダークモードって？
　一般的なWebサイトは、背景が白、文字色が黒を基調とした配色になっています。今ご覧になってるQiitaもそうですね。
　それに対してダークモードとは、主に背景が黒、文字色が白を基調とした配色です。目に優しい・見やすいなどの特徴があり、YoutubeやGoogleのアプリ、iPhoneのメールボックスなどでダークモードへの切替ができるようになってます。
　一見、実装するのが難しそうにも思えますが、普通のWebサイトであればCSSとJavaScriptだけで簡単に実装できると思ったので、今回はその紹介・解説をいたします。

### 実装環境
- 対象：　　HTMLとCSSで制作したWebサイト
- 実行日：　2021年10月6日
- 環境：　　windows10、Chrome

#① 元サイトの準備
　今回、記事を書くに至って紹介用のサイトを用意しました。
　以下がそのBeforeです。

[こちらで実際のBeforeページを開けます。
](https://hal0210.github.io/Qiita/Darkmode/before/)
　簡単に説明すると、こんなページです。
- ヘッダー背景がシアン
- CSSの「リセット用」で余計な余白を消した
- ダークモード用のボタンは`id='darkmode'`で指定

![Darkmodeサイト.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2088977/40a9785a-771d-f829-43e0-4825eb68f382.png)


```index.html
<!DOCTYPE html>
<html>
<head>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <header>Darkmode解説ページ</header>
  <main>
    <h1>Hello World!</h1>
    <p>このページはダークモードを解説する為に作られました</p>
    <div id='darkmodeBtn'>ダークモード</div>
  </main>
  <script src="darkmode.js"></script>
</body>
</html>
```

```styly.css
/* リセット用 */
* {
  margin: 0;
  padding: 0;
}

/* 通常CSS */
header {
  background-color: cyan;
  text-align: center;
}

main {
  padding: 0 20px;
}

#darkmodeBtn {
  background-color: gray;
  color: white;
  width: 150px;
  text-align: center;
  cursor: pointer;
  user-select: none;
}

#darkmodeBtn:hover {
  opacity: 0.7;
}
```

#② ダークモードのCSSを追加する
　ダークモードに切り替えた時のCSSを用意しましょう。
　まず、html内の`<body>`に属性として`class='dark'`を付けましょう。これでダークモード時のデザインを決めることが出来ます。
　次に、CSSで`.dark`に対するカラーリングの追加をしましょう。今回は以下のようにしました。

　簡単に説明すると、こんな感じです。
- 背景色を黒、文字色をシルバー
- ヘッダー背景は紺色
- ダークモード用のボタン色も調整
![スクリーンショット (72).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2088977/fc007823-f8f2-c215-5450-8f6a0b11da1b.png)

```style(追加分).css
/* ダークモードCSS */
.dark {
  background-color: black;
  color: silver;
}

.dark header {
  background-color: midnightblue;
}

.dark #darkmodeBtn {
  background-color: silver;
  color: black;
}
```

　今回はこのようにしましたが、実際のページに合わせて`.dark`のCSSを調節しましょう。
　デザインが出来たら、`body`の`class`属性を元に戻しておきましょう。

#③ JavaScriptで切替ボタンを作る。
　では、実際にダークモード用のボタンを実装しましょう。
　まず、コードを載せます。

```darkmode.js
const body = document.querySelector('body');
const darkmodeBtn = document.getElementById('darkmodeBtn');

darkmodeBtn.addEventListener('click', () => {
  body.classList.toggle('dark');
});
```

　ではコードの解説をいたします。
　まず、`html`から`body`と`<div id='darkmodeBtn'>`を取得します。
　ダークモード用ボタンに、『クリックしたら`body`のクラスの`dark`を切り替える』というイベントを付けました。
　これで、通常時にボタンを押すとダークモード、ダークモード時にボタンを押すと通常モードに切り替わるようになります。
　[実際のページがこちら](https://hal0210.github.io/Qiita/Darkmode/after/)

#④ ダークモードを記憶する
　JavaScriptのlocalStorageを使うことで、ダークモードの情報を保存できるとのコメントを頂いたので、実装してみたいと思います。

```darkmode.js
const body = document.querySelector('body');
const darkmodeBtn = document.getElementById('darkmodeBtn');

var mode = localStorage.getItem('mode');
if (mode === 'dark') {
  body.classList.add('dark');
}

darkmodeBtn.addEventListener('click', () => {
  body.classList.toggle('dark');
  if (mode === 'normal') {
    localStorage.setItem('mode', 'dark');
    mode = 'dark';
  } else {
    localStorage.setItem('mode', 'normal');
    mode = 'normal';
  }
});
```

### コード解説
　`mode`という変数を用意します。ここには`localStorage`の`mode`データを取得します。
　次に、ページ表示時にダークモードだった場合、`body`のクラス属性に`dark`を付けるようにします。
　また、切替ボタンのイベントに`localStorage`の`mode`データを変更し、`mode`変数も切り替えておきます。
　あと念のため`mode`データを消去できるボタンを追加しました。
　これで、画面遷移にも対応するダークモードが作れました。
[実際のページがこちら](https://hal0210.github.io/Qiita/Darkmode/addLocalStorage/index.html)

### localStorageについて
　localStorageについては[公式ドキュメント](https://developer.mozilla.org/ja/docs/Web/API/Window/localStorage)が分かりやすいのでそちらを参照ください。

　今回は`localStorage`を使用しましたが、`localStorage`は保持期間に制限がなく、セキュリティ的な問題があるそうなので、機密情報などの記録には注意した方が良いようです。まあ、ダークモードの情報を保存するだけなら大丈夫だと思います。
　`localStorage`の代わりに`sessionStorage`というものがあります。こちらはセッション終了（ブラウザを閉じる）で情報がクリアされます。したがって、`sessionStorage`の方がセキュアらしいです。ブラウザを閉じてダークモードがリセットされてもいいよって場合は`sessionStorage`で代用可能です。

## まとめ
　これでWebサイトのダークモードは実装可能です。
　CSSとJavaScriptの短めのスクリプトだけで簡単に実装することが出来るので、コスパは良いと思います。簡単なポートフォリオサイトとかをお持ちの方には良い機能ではないでしょうか。また現在時刻を取得して自動で切り替えるのも良いかもしれませんね。
　今回、『④ダークモードを記憶する』の段落はコメントで「LocalStorageで別ページにも適応できる」と頂いたので、その方法を調べてまとめました。情報提供いただいた`Minaki-web`さんに感謝申し上げます。
　初心者の拙い記事でしたが、閲覧ありがとうございました。