JavaScript

Pure Javascript:リンクジャンプ時のスクロールアニメーションのテンプレート

はじめに

自分のポートフォリオサイトを作った際にリンクジャンプでの画面スクロールアニメーションを実装したので,テンプレートにしてみた.かなり短いコードでそこそこいい感じに動いているっぽいです.(わざとかなり冗長的に書いています)

テンプレートページ

http://kyomesuke.com/scroll_template/index.html
動作確認はSafariとChromeとFirefoxでしました.

HTMLのコード

index.html
<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <link href="main.css" rel="stylesheet" type="text/css">
    <title>Scroll Template</title>
</head>
<body>
    <header>
        <h2 id="top_title">Scroll Template</h2>
        <h3 class="menuItem" id="sec1_link">Section1</h3>
        <h3 class="menuItem" id="sec2_link">Section2</h3>
        <h3 class="menuItem" id="sec3_link">Section3</h3>
        <h3 class="menuItem" id="sec4_link">Section4</h3>
    </header>
    <section id="dummy"></section>
    <section id="sec1">
        <h2 class="title">Section1</h2>
        ああああああああああああああああああああ
    </section>
    <section id="sec2">
        <h2 class="title">Section2</h2>
        いいいいいいいいいいいいいいいいいいいい
    </section>
    <section id="sec3">
        <h2 class="title">Section3</h2>
        うううううううううううううううううううう
    </section>
    <section id="sec4">
        <h2 class="title">Section4</h2>
        ええええええええええええええええええええ
    </section>
    <script type="text/javascript" src="main.js"></script>
</body>
</html>

Javascriptのコード

main.js
var scrollBody = document.scrollingElement

var sec1Link = document.getElementById("sec1_link");
var sec2Link = document.getElementById("sec2_link");
var sec3Link = document.getElementById("sec3_link");
var sec4Link = document.getElementById("sec4_link");

var dummy = document.getElementById("dummy");
var sec1 = document.getElementById("sec1");
var sec2 = document.getElementById("sec2");
var sec3 = document.getElementById("sec3");
var sec4 = document.getElementById("sec4");
var timer;
const speed = 50;

function delta(obj) {
    var scrollMax = document.body.clientHeight - window.innerHeight
    var goal = obj.offsetTop - dummy.clientHeight;
    var offset = goal - scrollBody.scrollTop;
    if (Math.abs(offset) < speed) {
        scrollBody.scrollTo(0, goal);
    } else {
        scrollBody.scrollBy(0, 0 < offset ? speed : -speed);
        if (scrollBody.scrollTop + speed <= scrollMax) {
            timer = setTimeout(function(){ delta(obj); }, 5);
        } else {
            scrollBody.scrollTo(0, scrollMax);
        }
    }
}

window.onload = function() {
    sec1Link.addEventListener("click", function() {
        clearTimeout(timer);
        timer = setTimeout(function(){ delta(sec1); }, 5);
    }, false);
    sec2Link.addEventListener("click", function() {
        clearTimeout(timer);
        timer = setTimeout(function(){ delta(sec2); }, 5);
    }, false);
    sec3Link.addEventListener("click", function() {
        clearTimeout(timer);
        timer = setTimeout(function(){ delta(sec3); }, 5);
    }, false);
    sec4Link.addEventListener("click", function() {
        clearTimeout(timer);
        timer = setTimeout(function(){ delta(sec4); }, 5);
    }, false);
}

CSSのコード

main.css
body {
    margin: 0;
    padding: 0;
    width: 100%;
    height: 100%;
    text-align: center;
    background-color: #777777;
}

header {
    position: fixed !important;
    top: 0px;
    left: 0px;
    width: 100%;
    min-width: 800px;
    height: 80px;
    text-align: left;
    color: #27292A;
    background-color: #0097A7;
    display: flex;
    display: -webkit-flex;
    display: -moz-flex;
    display: -ms-flex;
    user-select: none;
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
}

header h2#top_title {
    position: absolute;
    margin: 0px 5px 0px 5px;
    padding: 0px;
    top: 0px;
    left: 35px;
    line-height: 80px;
}

header h3.menuItem {
    position: absolute;
    margin: 0px 5px 0px 5px;
    padding: 0px;
    top: 0px;
    line-height: 80px;
}

header h3.menuItem:hover {
    cursor: pointer;
    color: #666666;
}

header h3#sec1_link {
    right: 340px;
}

header h3#sec2_link {
    right: 240px;
}

header h3#sec3_link {
    right: 140px;
}

header h3#sec4_link {
    right: 40px;
}

section#dummy {
    width: 100%;
    height: 80px;
}

section#sec1 {
    width: 100%;
    height: 343px;
    background-color: #90CAF9;
}

section#sec2 {
    width: 100%;
    height: 421px;
    background-color: #F8BBD0;
}

section#sec3 {
    width: 100%;
    height: 407px;
    background-color: #C8E6C9;
}

section#sec4 {
    width: 100%;
    height: 578px;
    background-color: #FFECB3;
}

h2.title {
    margin: 0 auto;
    padding: 15px 0px;
    font-size: 50px;
    color: #27292A;
}