スクロールで動的にWebサイトのナビゲーションバー・Android版Chromeのアドレスバーの色を変更する!!

# 背景
Webサイトをデザインするときに、スクロールしたときにナビゲーションバーの色を変えたくなったので実装してみました。
実装には、jQueryを使用しました。
ついでに、Android版Chromeのアドレスバーの色(theme-colorを使って変更)もスクロールで変えられるようにしています。

今回の実装にあまり関係ないですが、CSSフレームワークには

* [cirrus](https://spiderpig86.github.io/Cirrus/)

を使っています。

# デモ
Android端末
<blockquote class="twitter-tweet" data-lang="ja"><p lang="und" dir="ltr"><a href="https://t.co/pu1zHpcaDx">pic.twitter.com/pu1zHpcaDx</a></p>&mdash; jong (@fashioncrazy66) <a href="https://twitter.com/fashioncrazy66/status/1046068206572589057?ref_src=twsrc%5Etfw">2018年9月29日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

PC
<blockquote class="twitter-tweet" data-lang="ja"><p lang="und" dir="ltr"><a href="https://t.co/boDoeo0FqY">pic.twitter.com/boDoeo0FqY</a></p>&mdash; jong (@fashioncrazy66) <a href="https://twitter.com/fashioncrazy66/status/1046428463794610178?ref_src=twsrc%5Etfw">2018年9月30日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


# 考え方
1. スクロール後のナビゲーションバーの色などをcssのクラスとして定義しておきます。
2. スクロールをjQueryで検知して、ナビゲーションバーなどにスクロール後の色を定義したクラスを付加します。(ページトップに戻ってきたときは、付加したクラスを削除します。)
3. 色がスクロールに応じて変わるのでいい感じになります。

# 実装
まずはHTMLから

```html:index.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0">
  <title>デモ</title>
  <meta name="theme-color" content="#fafafa">
  <link rel="stylesheet" href="./assets/css/cirrus.css">
  <link rel="stylesheet" href="./assets/css/style.css">
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.3.1/css/all.css" integrity="sha384-mzrmE5qonljUremFsqc01SB46JvROS7bZs3IO2EmfFsd15uHvIt+Y8vEf7N7fWAU" crossorigin="anonymous">
  <link rel="icon" href="./favicon.ico">
  <link rel="apple-touch-icon" href="./favicon_128.png">
</head>
<body>
  <header>
    <div id="header" class="header header-fixed unselectable header-animated">
      <div class="header-brand">
        <div class="nav-item nav-btn" id="header-btn">
          <span></span>
          <span></span>
          <span></span>
        </div>
      </div>
      <div class="header-nav" id="header-menu">
        <div class="nav-right">
          <div class="nav-item">
            <a href="#about">About us</a>
          </div>
          <div class="nav-item">
            <a href="#contact">Contact</a>
          </div>
          <div class="nav-item">
            <a href="#access">Access</a>
          </div>
          <div class="header_logo_center">
            <div class="nav-item text-center">
              <a href="https://www.facebook.com/sharer/sharer.php?u=" target="_blank">
                    <span class="icon">
                        <i class="fab fa-facebook-f"></i>
                    </span>
                </a>
            </div>
            <div class="nav-item text-center">
              <a href="https://twitter.com/share?url=" target="_blank">
                    <span class="icon">
                        <i class="fab fa-twitter"></i>
                    </span>
                </a>
            </div>
            <div class="nav-item text-center">
              <a href="https://plus.google.com/share?url=" target="_blank">
                    <span class="icon">
                        <i class="fab fa-google-plus"></i>
                    </span>
                </a>
            </div>
            <div class="nav-item text-center">
              <a href="http://line.me/R/msg/text/?" target="_blank">
                    <span class="icon">
                        <i class="fab fa-line"></i>
                    </span>
                </a>
            </div>
          </div>
        </div>
      </div>
    </div>
  </header>
```

以下の部分で、Android版Chromeのアドレスバーの初期の色を設定しています。

```html
<meta name="theme-color" content="#fafafa">
```

cssは今回の実装に関連する部分のみ。
スクロール後の色などを定義しておきます。
transitionを指定しておくといい感じにフワッと色が変わります。

```css
/*ナビゲーションバーの初期の色などを定義*/
.header {
    -webkit-box-flex: 1;
    -ms-flex-positive: 1;
    flex-grow: 1;
    -ms-flex-negative: 0;
    width: 100%;
    z-index: 100;
    margin-bottom: 20px;
    box-shadow: 0 3px 15px rgba(57, 63, 72, 0.1);
    max-height: 100vh;
    background: rgba(250,250,250,0.3);
}

/*スクロール後のナビゲーションバーの色を定義*/
.topHeader {
  background: rgba(22, 94, 131, 0.9) !important;
  border: rgba(22, 94, 131, 0.9) !important;
  transition: 0.3s; /*フワッと色を変えるためにtransitionを設定します*/
}

/*スクロール後のナビゲーションバーのリンクの色を定義*/
.whitelink {
  color: #fafafa !important;
  transition: 0.3s;
}

/*スクロール後のハンバーガーメニューの色を定義*/
.whitespan {
  background-color: #fafafa !important;
  transition: 0.3s;
}

/*ページトップに戻ってきたときにフワッとナビゲーションバーの色を戻す*/
.rmtopHeader {
  transition: 0.3s;
}
```

今回のキモになるスクロールを検知して、適切なクラスを付加する処理を書きます。
スクロール検知時に付加した、「.topHeader」クラスなどをページトップに戻ってきたときには削除することでうまく色を切り替えられます。

```javascript:change-headercolor.js
$(document).scroll(function() {
  var scroll = $(window).scrollTop();
  var head = $('head');
  var headChildren = head.children();
  var childrenLength = headChildren.length;

  if (scroll >= 1) {
//スクロール時に以下を実行
    $("#header").addClass("topHeader");
    $("a").addClass("whitelink");
    $(".nav-btn span").addClass("whitespan");
    
//<head>タグ内の要素を探索し、<theme-color>タグのcontentを更新
    for (var i = 0; i < childrenLength; i++) {
      var metaName = headChildren.eq(i).attr('name');
      if (metaName === 'theme-color') {
        headChildren.eq(i).attr('content', '#165e83');
      }
    }
  } else {
//ページトップに戻ったとき以下を実行
    $("#header").removeClass("topHeader");
    $("#header").addClass("rmtopHeader");
    $("a").removeClass("whitelink");
    $(".nav-btn span").removeClass("whitespan");
    
//<head>タグ内の要素を探索し、theme-colorのcontentを更新
    for (var i = 0; i < childrenLength; i++) {
      var metaName = headChildren.eq(i).attr('name');
      if (metaName === 'theme-color') {
        headChildren.eq(i).attr('content', '#fafafa');
      }
    }
  }
});
```

# まとめ
<meta>タグの情報もうまくやれば更新できます。
theme-colorの色も動的に変更できることがわかりました。