どうも、くまだです。
スクロールしたらヘッダーの背景色を変える方法の実装メモ。よくあるやつです。
LPデザインのお仕事募集中です↓↓↓
【JavaScript】スクロールしたらヘッダーの背景色を変える
スクロールしたらヘッダーの背景色を変えるコードは以下になります。
<div class="l-container">
<header class="l-header p-header" id="js-header">
<div class="p-header__inner">
<h1 class="p-header__title" id="logo-label">
<a href="" aria-labelledby="logo-label">ロゴ</a>
</h1>
<div class="p-header__hamburger">
<button class="c-hamburger" aria-expanded="false" aria-label="メニューを開く">
</button>
</div>
<nav class="p-header__nav p-nav" aria-expanded="false">
<div class="p-nav__inner">
<ul class="p-nav__list">
<li class="p-nav__item">
<a href="#" class="p-nav__link">メニュー</a>
</li>
<li class="p-nav__item">
<a href="#" class="p-nav__link">メニュー</a>
</li>
<li class="p-nav__item">
<a href="#" class="p-nav__link">メニュー</a>
</li>
<li class="p-nav__item">
<a href="#" class="p-nav__link">メニュー</a>
</li>
</ul>
</div>
</nav>
</div>
</header>
<main>
<div class="main" id="js-mainVisual">メインビジュアル</div>
<div class="contents">メインコンテンツ</div>
</main>
</div>
ul,
li {
list-style: none;
}
p {
margin: 0;
}
a {
text-decoration: none;
}
.main {
padding-top: 72px;
background: skyblue;
height: 700px;
}
.contents {
height: 2000px;
background-color: orange;
}
.l-header {
display: block;
z-index: 999;
position: fixed;
top: 0;
right: 0;
left: 0;
width: 100%;
height: 72px;
background-color: #fff;
}
.l-header.change-color {
background-color: lightcoral;
}
.c-hamburger {
position: relative;
width: inherit;
height: inherit;
margin: 0;
cursor: pointer;
background-color: lightblue;
}
.c-hamburger::after {
position: absolute;
content: '';
width: 6px;
height: 6px;
background: red;
display: block;
left: calc(50% - 4px);
top: calc(50% - 4px);
box-shadow: -12px 0 0 orange, 12px 0 0 orange, -12px -12px 0 orange, 0 -12px 0 orange, 12px -12px 0 orange, -12px 12px 0 orange, 0 12px 0 orange, 12px 12px 0 orange;
transition: box-shadow .4s;
}
.c-hamburger::before {
opacity: 0;
content: "";
position: absolute;
width: 40px;
height: 1px;
background: orange;
transform: translate(-50%, -50%) rotate(135deg);
top: 50%;
left: 50%;
transition: opacity .4s;
}
.c-hamburger[aria-expanded="true"]::before {
opacity: 1;
}
.c-hamburger[aria-expanded="true"]::after {
box-shadow: initial;
content: "";
position: absolute;
width: 40px;
height: 1px;
background: orange;
transform: translate(-50%, -50%) rotate(45deg);
top: 50%;
left: 50%;
}
.p-header__nav {
display: flex;
z-index: 10;
position: absolute;
top: 0;
right: -100%;
flex-direction: column;
align-items: center;
justify-content: center;
width: 100%;
height: 100vh;
background: transparent;
font-weight: 700;
opacity: 0;
transition: 0.6s;
}
@media screen and (min-width:768px) {
.p-header__nav {
position: static;
height: 100%;
opacity: initial;
align-items: flex-end;
}
}
.p-header__inner {
display: flex;
align-items: center;
justify-content: space-between;
height: inherit;
padding: 13px 20px;
}
.p-header__title {
width: 100%;
max-width: 120px;
height: 48px;
background: lightgray;
}
.p-header__title a {
display: block;
width: 100%;
height: auto;
}
.p-header__title a img {
height: 100%;
}
.p-header__hamburger {
z-index: 100;
position: absolute;
top: 0;
right: 0;
width: 95px;
height: 100%;
}
@media screen and (min-width:768px) {
.p-header__hamburger {
display: none;
}
}
.p-header__nav[aria-expanded="true"] {
position: fixed;
top: 0;
right: 0;
background: lightblue;
opacity: 1;
transition: 0.6s;
}
.p-nav {
padding-top: 72px;
padding-bottom: 72px;
}
@media screen and (min-width:768px) {
.p-nav {
padding-top: 16px;
padding-bottom: 16px
}
}
.p-nav__list {
display: block;
width: 100%;
padding-right: 20px;
padding-left: 20px;
background: lightblue;
}
@media screen and (min-width:768px) {
.p-nav__list {
display: flex;
background: inherit;
padding-right: 0;
}
}
.p-nav__item {
position: relative;
width: 100%;
}
.p-nav__link {
display: block;
width: 100%;
height: 100%;
padding: 20px;
text-align: center;
}
document.addEventListener("DOMContentLoaded", function () {
const imgHeight = document.querySelector("#js-mainVisual").offsetHeight;
const header = document.querySelector("#js-header");
window.addEventListener("scroll", function () {
if (window.scrollY < imgHeight) {
header.classList.remove("change-color");
} else {
header.classList.add("change-color");
}
});
});
ヘッダーはfixedで固定、スクロールしてメインビジュアルを過ぎたらヘッダーの背景色が変わり、メインビジュアルより上にスクロールするとヘッダーの背景色が元の色に戻る処理。よく見かけるやつです。
以下の部分でヘッダーの要素を取得して変数に格納。
const header = document.querySelector("#js-header");
以下の部分で、メインビジュアルの要素の高さを取得して変数に格納。
const imgHeight = document.querySelector("#js-mainVisual").offsetHeight;
if文で、ウィンドウの現在スクロール位置がimgHeight未満であれば、headerからchange-colorクラスを外す。そうでない場合、つまりウィンドウの現在スクロール位置がimgHeight以上であれば、change-colorクラスを付与。
if (window.scrollY < imgHeight) {
header.classList.remove("change-color");
} else {
header.classList.add("change-color");
}
それをaddEventListenerでスクロールイベントを登録。
window.addEventListener("scroll", function () {
if (window.scrollY < imgHeight) {
header.classList.remove("change-color");
} else {
header.classList.add("change-color");
}
});
よくある実装なので、テンプレにしてます。
ここまで読んでくださりありがとうございました。