スクロールに追従したナビゲーション(ページ内リンク)のカレント表示についてのコード記録。
目次
カレント表示とは
こんな感じのアニメーション。(動画右上のナビゲーションリンクのアンダーバー)
ページ内をスクロールすると各セクションと紐づいたナビゲーションリンクにアニメーションが付与される。
ページ内のどこを見ているのかわかりやすく、ユーザフレンドリーなサイトに。
JavaScriptコード(jQuery)
$(function () {
// navカレント表示
var set = 200; //ウインドウ上部からどれぐらいの位置で変化させるか
var boxTop = new Array();
var current = -1;
//各要素の位置
//position-nowは場所を取得したい対象の要素に付ける
$(".position-now").each(function (i) {
boxTop[i] = $(this).offset().top;
});
//最初の要素にclass="position-now"をつける
changeBox(0);
//スクロールした時の処理
$(window).scroll(function () {
scrollPosition = $(window).scrollTop();
for (var i = boxTop.length - 1; i >= 0; i--) {
if ($(window).scrollTop() > boxTop[i] - set) {
changeBox(i);
break;
}
}
});
//ナビの処理
function changeBox(secNum) {
if (secNum != current) {
current = secNum;
secNum2 = secNum + 1; //以下にクラス付与したい要素名と付与したいクラス名
$(".header nav ul li a").removeClass("link-current");
//位置によって個別に処理をしたい場合
if (current == 0) {
$("#about_link_js").addClass("link-current");
// 現在地がsection1の場合の処理
} else if (current == 1) {
$("#skills_link_js").addClass("link-current");
// 現在地がsection2の場合の処理
} else if (current == 2) {
// 現在地がsection3の場合の処理
$("#service_link_js").addClass("link-current");
} else if (current == 3) {
// 現在地がsection4の場合の処理
$("#flow_link_js").addClass("link-current");
} else if (current == 4) {
// 現在地がsection5の場合の処理
$("#works_link_js").addClass("link-current");
} else if (current == 5) {
// 現在地がsection6の場合の処理
$("#contact_link_js").addClass("link-current");
}
}
}
});
$(function () {
// スムーススクロール
$('a[href^="#"]').click(function () {
let header = $(".header").innerHeight();
let speed = 500;
let id = $(this).attr("href");
let target = $("#" == id ? "html" : id);
let position = $(target).offset().top - header;
$("html, body").animate(
{
scrollTop: position,
},
speed
);
return false;
});
});
実装手順
jQueryコードをコピペ
上記jQueryコードをコピペ。
※ラストのスムーススクロールのコードは、既に記述済みの場合は除外。
カレント判定したいタグ全てにクラス付与
カレント判定したいタグ(ナビゲーションに記載しているsectionやdiv)全てにclass=“position-now”
を付与。
各navメニューに固有のidを付与
各navメニューに任意のidを付与(例えばid=”**_link_js”
のように付けておく)。
30行目付近の 「//位置によって個別に処理をしたい場合」内のid名(#top_link_js等)を任意の内容に書き換える。
※このコピペ用コードはナビメニューが5つの場合(current0~4)を想定。増やしたい場合は追加する数だけ else if{} を増やしす、減らす場合は else if{} を減らす。
ページ内リンクを付ける
例えばナビゲーション内のaboutならhref="#about"
とし、それに紐づくtopセクションにid=”top”
を付与。
CSSにアニメーション用スタイルを付与
好きなスタイルを付与する。
例:黒の下線
.link-current {
border-bottom: 2px solid #fff;
}
カレント表示させたい要素を指定
27行目付近の.header-nav li a
の部分にカレント表示させたい任意の要素を指定。
→各々のナビゲーション、リンクを指定する。
アニメーションのタイミング調整
タイミング調整は3行目付近の
var set = 250;
の数値をいじる。
(補足)スムーススクロール設定
固定ヘッダーを想定し、ヘッダー分の高さを差し引く処理を入れてある為、必要に応じて修正。
対象は下記部分。
let header = $(".header").innerHeight();
let position = $(target).offset().top - header;
実装例に対応したHTML,CSSコード例
実装例のスクリプトを記載したHTML,CSSコードの参考コード。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<!-- jquery -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<style>
@charset "UTF-8";
/*==========================================================================
# reset
==========================================================================*/
*,
::before,
::after {
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
html,
body,
h1,
h2,
h3,
h4,
h5,
h6,
ul,
ol,
dl,
li,
dt,
dd,
p,
div,
span,
img,
a,
table,
tr,
th,
td {
margin: 0;
padding: 0;
border: 0;
font-weight: normal;
font-size: 100%;
vertical-align: baseline;
}
header,
footer,
nav,
section,
article,
main,
aside,
figure,
figcaption {
display: block;
}
ol,
ul {
list-style: none;
list-style-type: none;
}
img {
max-width: 100%;
height: auto;
vertical-align: middle;
}
a {
color: inherit;
text-decoration: none;
}
/*==========================================================================
# カレント表示
==========================================================================*/
.link-current {
border-bottom: 2px solid #000;
}
/*==========================================================================
# body内
==========================================================================*/
.header {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 80px;
background: #bbbbbb;
}
.header nav {
position: relative;
height: inherit;
}
.header nav ul {
height: inherit;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
}
.header nav ul li {
list-style: none;
}
.header nav ul li:not(:first-child) {
margin-left: 40px;
}
main {
margin-top: 80px;
}
.section {
height: 600px;
}
.section:nth-child(2n + 1) {
background: #d2ffbb;
}
.section:nth-child(2n) {
background: #bbc6ff;
}
.section:last-child {
margin-bottom: 300px;
}
.section-head {
text-align: center;
font-size: 40px;
}
</style>
<script>
$(function () {
// navカレント表示
var set = 200; //ウインドウ上部からどれぐらいの位置で変化させるか
var boxTop = new Array();
var current = -1;
//各要素の位置
//position-nowは場所を取得したい対象の要素に付ける
$(".position-now").each(function (i) {
boxTop[i] = $(this).offset().top;
});
//最初の要素にclass="position-now"をつける
changeBox(0);
//スクロールした時の処理
$(window).scroll(function () {
scrollPosition = $(window).scrollTop();
for (var i = boxTop.length - 1; i >= 0; i--) {
if ($(window).scrollTop() > boxTop[i] - set) {
changeBox(i);
break;
}
}
});
//ナビの処理
function changeBox(secNum) {
if (secNum != current) {
current = secNum;
secNum2 = secNum + 1; //以下にクラス付与したい要素名と付与したいクラス名
$(".header nav ul li a").removeClass("link-current");
//位置によって個別に処理をしたい場合
if (current == 0) {
$("#about_link_js").addClass("link-current");
// 現在地がsection1の場合の処理
} else if (current == 1) {
$("#skills_link_js").addClass("link-current");
// 現在地がsection2の場合の処理
} else if (current == 2) {
// 現在地がsection3の場合の処理
$("#service_link_js").addClass("link-current");
} else if (current == 3) {
// 現在地がsection4の場合の処理
$("#flow_link_js").addClass("link-current");
} else if (current == 4) {
// 現在地がsection5の場合の処理
$("#works_link_js").addClass("link-current");
} else if (current == 5) {
// 現在地がsection6の場合の処理
$("#contact_link_js").addClass("link-current");
}
}
}
});
$(function () {
// スムーススクロール
$('a[href^="#"]').click(function () {
let header = $(".header").innerHeight();
let speed = 500;
let id = $(this).attr("href");
let target = $("#" == id ? "html" : id);
let position = $(target).offset().top - header;
$("html, body").animate(
{
scrollTop: position,
},
speed
);
return false;
});
});
</script>
</head>
<body>
<header class="header">
<nav>
<ul>
<li><a id="about_link_js" href="#about">About</a></li>
<li><a id="skills_link_js" href="#skills">Skills</a></li>
<li><a id="service_link_js" href="#service">Service</a></li>
<li><a id="flow_link_js" href="#flow">Workflow</a></li>
<li><a id="works_link_js" href="#works">Works</a></li>
<li><a id="contact_link_js" href="#contact">Contact</a></li>
</ul>
</nav>
</header>
<!-- /.header -->
<main>
<section class="section position-now" id="about about_link_js">
<h2 class="section-head">About</h2>
</section>
<!-- /.about -->
<section class="section position-now" id="skills skills_link_js">
<h2 class="section-head">Skills</h2>
</section>
<section class="section position-now" id="service service_link_js">
<h2 class="section-head">Service</h2>
</section>
<!-- /.service -->
<section class="section position-now" id="flow flow_link_js">
<h2 class="section-head">Work Flow</h2>
</section>
<!-- /.flow -->
<section class="section position-now" id="works works_link_js">
<h2 class="section-head">Works</h2>
</section>
<!-- /.works -->
<section class="section position-now" id="contact contact_link_js">
<h2 class="section-head">Contact</h2>
</section>
<!-- /.contact -->
</main>
</body>
</html>
コメント