新しいブラウザでは、CSSのscroll-behaviorプロパティの設定で実現できます。
詳細はこちらの記事を参照してください。
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title></title>
<link rel="stylesheet" type="text/css" href="AnchorScrollNative.css" />
<script type="text/javascript">
window.onload = function () {
document.getElementById('link1').onclick = function () {
var top = getElementAbsoluteTop('section1');
scrollScreen(top, 20);
return false;
}
document.getElementById('link2').onclick = function () {
var top = getElementAbsoluteTop('section2');
scrollScreen(top, 20);
return false;
}
document.getElementById('link3').onclick = function () {
var top = getElementAbsoluteTop('section3');
scrollScreen(top, 20);
return false;
}
document.getElementById('link4').onclick = function () {
var top = getElementAbsoluteTop('section1');
scrollScreen(top, 20);
return false;
}
document.getElementById('link5').onclick = function () {
var top = getElementAbsoluteTop('section2');
scrollScreen(top, 20);
return false;
}
document.getElementById('link6').onclick = function () {
var top = getElementAbsoluteTop('section3');
scrollScreen(top, 20);
return false;
}
};
function getElementAbsoluteTop(id) {
var target = document.getElementById(id);
var rect = target.getBoundingClientRect();
return rect.top;
}
function scrollScreen(desty, time) {
var top = Math.floor(document.documentElement.scrollTop || document.body.scrollTop);
var tick = desty / time;
if (top < desty) {
var newy = top + tick;
document.documentElement.scrollTop = newy;
setTimeout("scrollScreenDown(" + top + "," + desty + "," + newy + "," + tick + ")", 20);
} else {
var newy = top + tick;
document.documentElement.scrollTop = newy;
setTimeout("scrollScreenUp(" + top + "," + desty + "," + newy + "," + tick + ")", 20);
}
}
function scrollScreenDown(starty, desty, newy, tick) {
if (newy < starty + desty) {
var newy = newy + tick;
if (starty + desty < newy) newy = starty + desty;
document.documentElement.scrollTop = newy;
setTimeout("scrollScreenDown(" + starty + "," + +desty + "," + newy + "," + tick + ")", 20);
}
}
function scrollScreenUp(starty, desty, newy, tick) {
if (starty + desty < newy) {
var newy = newy + tick;
if (starty + desty > newy) newy = starty + desty;
document.documentElement.scrollTop = newy;
setTimeout("scrollScreenUp(" + starty + "," + desty + "," + newy + "," + tick + ")", 20);
}
}
</script>
</head>
<body>
<a id="link1" href="#section1">セクション1へ</a><br />
<a id="link2" href="#section2">セクション2へ</a><br />
<a id="link3" href="#section3">セクション3へ</a><br />
<hr />
<a id="section1">セクション1</a>
<div style="height:300px">コンテンツ</div>
<a id="section2">セクション2</a>
<div style="height:300px">コンテンツ</div>
<a id="section3">セクション3</a>
<div style="height:300px">コンテンツ</div>
<a id="link4" href="#section1">セクション1へ</a><br />
<a id="link5" href="#section2">セクション2へ</a><br />
<a id="link6" href="#section3">セクション3へ</a><br />
<hr />
</body>
</html>
document.getElementById('link1').onclick = function () {
var top = getElementAbsoluteTop('section1');
scrollScreen(top, 20);
return false;
}
Clickイベントとして割り当てた関数が上記になります。getElementAbsoluteTop()関数を呼び出し、与えたIDの要素の縦方向の絶対位置を求めます。求めた絶対位置をscrollScreen()関数に与えてスクロールします。第二引数は何分割してアニメーションするか(フレーム数)を指定します。 function getElementAbsoluteTop(id) {
var target = document.getElementById(id);
var rect = target.getBoundingClientRect();
return rect.top;
}
与えたIDの要素の上端の絶対位置を求める関数です。処理内容は、document.getElementById()メソッドで与えたIDの要素を取得し、getBoundingClientRect()メソッドで要素を囲む矩形の座標を取得しそのtopの値を戻り値として戻します。function scrollScreen(desty, time) {
var top = Math.floor(document.documentElement.scrollTop || document.body.scrollTop);
var tick = desty / time;
if (top < desty) {
var newy = top + tick;
document.documentElement.scrollTop = newy;
setTimeout("scrollScreenDown(" + top + "," + desty + "," + newy + "," + tick + ")", 20);
} else {
var newy = top + tick;
document.documentElement.scrollTop = newy;
setTimeout("scrollScreenUp(" + top + "," + desty + "," + newy + "," + tick + ")", 20);
}
}
スクロール開始のための関数です。スクロールさせる量をフレーム数で割って1回あたりのスクロール量(tick)を求めます。現在のスクロール位置からtick分だけスクロールさせます。その後setTimeout関数を呼び出し20ms後に次の関数を呼び出します。上に向かってスクロールする場合はscrollScreenUp()関数、下に向かってスクロールする場合はscrollScreenDown()関数を呼び出します。function scrollScreenDown(starty, desty, newy, tick) {
if (newy < starty + desty) {
var newy = newy + tick;
if (starty + desty < newy) newy = starty + desty;
document.documentElement.scrollTop = newy;
setTimeout(function(){scrollScreenDown(starty, desty, newy, tick);}, 20);
}
}
下方向に向かってスクロールする関数です。現在のスクロール位置からtick文スクロールします。その後、setTimeout関数を呼び出し20ms後にs同じ(crollScreenDown())関数を呼び出します。スクロールの位置が遷移先の位置になった場合はsetTimeout関数の呼び出しをせずにスクロールアニメーションを終了します。function scrollScreenUp(starty, desty, newy, tick) {
if (starty + desty < newy) {
var newy = newy + tick;
if (starty + desty > newy) newy = starty + desty;
document.documentElement.scrollTop = newy;
setTimeout(function(){scrollScreenUp(starty, desty, newy, tick);}, 20);
}
}
上方向に向かってスクロールする関数です。処理内容はcrollScreenDown()関数と同じです。<body>
<a id="link1" href="#section1">セクション1へ</a><br />
<a id="link2" href="#section2">セクション2へ</a><br />
<a id="link3" href="#section3">セクション3へ</a><br />
<hr />
<a id="section1">セクション1</a>
<div style="height:300px">コンテンツ</div>
<a id="section2">セクション2</a>
<div style="height:300px">コンテンツ</div>
<a id="section3">セクション3</a>
<div style="height:300px">コンテンツ</div>
<a id="link4" href="#section1">セクション1へ</a><br />
<a id="link5" href="#section2">セクション2へ</a><br />
<a id="link6" href="#section3">セクション3へ</a><br />
<hr />
</body>
HTML部分のコードです。ページ内へのリンクを設置するコードと同じです。リンク元のaタグにIDをつける必要があることに注意してください。 <script type="text/javascript">
window.onload = function () {
document.getElementById('link1').onclick = function () {
var top = getElementAbsoluteTop('section1');
scrollScreen(top, 20);
return false;
}
document.getElementById('link2').onclick = function () {
var top = getElementAbsoluteTop('section2');
scrollScreen(top, 20);
return false;
}
document.getElementById('link3').onclick = function () {
var top = getElementAbsoluteTop('section3');
scrollScreen(top, 20);
return false;
}
document.getElementById('link4').onclick = function () {
var top = getElementAbsoluteTop('section1');
scrollScreen(top, 20);
return false;
}
document.getElementById('link5').onclick = function () {
var top = getElementAbsoluteTop('section2');
scrollScreen(top, 20);
return false;
}
document.getElementById('link6').onclick = function () {
var top = getElementAbsoluteTop('section3');
scrollScreen(top, 20);
return false;
}
};
function getElementAbsoluteTop(id) {
var target = document.getElementById(id);
var rect = target.getBoundingClientRect();
return rect.top;
}
function scrollScreen(desty, time) {
var top = Math.floor(document.documentElement.scrollTop || document.body.scrollTop);
var tick = desty / time;
if (top < desty) {
var newy = top + tick;
document.documentElement.scrollTop = newy;
setTimeout(function(){scrollScreenDown(top, desty, newy, tick);}, 20);
} else {
var newy = top + tick;
document.documentElement.scrollTop = newy;
setTimeout(function(){scrollScreenUp(top, desty, newy, tick);}, 20);
}
}
function scrollScreenDown(starty, desty, newy, tick) {
if (newy < starty + desty) {
var newy = newy + tick;
if (starty + desty < newy) newy = starty + desty;
document.documentElement.scrollTop = newy;
setTimeout(function(){scrollScreenDown(starty, desty, newy, tick);}, 20);
}
}
function scrollScreenUp(starty, desty, newy, tick) {
if (starty + desty < newy) {
var newy = newy + tick;
if (starty + desty > newy) newy = starty + desty;
document.documentElement.scrollTop = newy;
setTimeout(function(){scrollScreenUp(starty, desty, newy, tick);}, 20);
}
}
</script>
setTimeout("scrollScreenUp(" + top + "," + desty + "," + newy + "," + tick + ")", 20);
setTimeout(function(){scrollScreenUp(starty, desty, newy, tick);}, 20);
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title></title>
<link rel="stylesheet" type="text/css" href="AnchorScrollNative.css" />
<script type="text/javascript">
window.onload = function () {
document.getElementById('link1').onclick = function () {
var top = getElementAbsoluteTop('section1');
scrollScreen(top, 20);
return false;
}
document.getElementById('link2').onclick = function () {
var top = getElementAbsoluteTop('section2');
scrollScreen(top, 20);
return false;
}
document.getElementById('link3').onclick = function () {
var top = getElementAbsoluteTop('section3');
scrollScreen(top, 20);
return false;
}
document.getElementById('link4').onclick = function () {
var top = getElementAbsoluteTop('section1');
scrollScreen(top, 20);
return false;
}
document.getElementById('link5').onclick = function () {
var top = getElementAbsoluteTop('section2');
scrollScreen(top, 20);
return false;
}
document.getElementById('link6').onclick = function () {
var top = getElementAbsoluteTop('section3');
scrollScreen(top, 20);
return false;
}
};
function getElementAbsoluteTop(id) {
var target = document.getElementById(id);
var rect = target.getBoundingClientRect();
return rect.top;
}
function scrollScreen(desty, time) {
var top = Math.floor(document.documentElement.scrollTop || document.body.scrollTop);
var tick = desty / time;
var newy = top + tick;
document.documentElement.scrollTop = newy;
setTimeout(function () { scrollScreenInt(top, desty, newy, tick); }, 20);
}
function scrollScreenInt(starty, desty, newy, tick) {
var stop=true;
var newy = newy + tick;
if (desty < 0) {
if (starty + desty < newy) {
stop = false;
} else {
newy = starty + desty;
}
} else {
if (newy < starty + desty) {
stop = false;
} else {
newy = starty + desty;
}
}
document.documentElement.scrollTop = newy;
if (stop == false) {
setTimeout(function () { scrollScreenInt(starty, desty, newy, tick); }, 20);
}
}
</script>
</head>
<body>
<a id="link1" href="#section1">セクション1へ</a><br />
<a id="link2" href="#section2">セクション2へ</a><br />
<a id="link3" href="#section3">セクション3へ</a><br />
<hr />
<a id="section1">セクション1</a>
<div style="height:300px">コンテンツ</div>
<a id="section2">セクション2</a>
<div style="height:300px">コンテンツ</div>
<a id="section3">セクション3</a>
<div style="height:300px">コンテンツ</div>
<a id="link4" href="#section1">セクション1へ</a><br />
<a id="link5" href="#section2">セクション2へ</a><br />
<a id="link6" href="#section3">セクション3へ</a><br />
<hr />
</body>
</html>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title></title>
<link rel="stylesheet" type="text/css" href="AnchorScrollNative.css" />
<script type="text/javascript">
function LinkClick(id) {
var top = getElementAbsoluteTop(id);
scrollScreen(top, 20);
return false;
}
function getElementAbsoluteTop(id) {
var target = document.getElementById(id);
var rect = target.getBoundingClientRect();
return rect.top;
}
function scrollScreen(desty, time) {
var top = Math.floor(document.documentElement.scrollTop || document.body.scrollTop);
var tick = desty / time;
var newy = top + tick;
document.documentElement.scrollTop = newy;
setTimeout(function () { scrollScreenInt(top, desty, newy, tick); }, 20);
}
function scrollScreenInt(starty, desty, newy, tick) {
var stop=true;
var newy = newy + tick;
if (desty < 0) {
if (starty + desty < newy) {
stop = false;
} else {
newy = starty + desty;
}
} else {
if (newy < starty + desty) {
stop = false;
} else {
newy = starty + desty;
}
}
document.documentElement.scrollTop = newy;
if (stop == false) {
setTimeout(function () { scrollScreenInt(starty, desty, newy, tick); }, 20);
}
}
</script>
</head>
<body>
<a href="#section1" onclick="return LinkClick('section1');">セクション1へ</a><br />
<a href="#section2" onclick="return LinkClick('section2');">セクション2へ</a><br />
<a href="#section3" onclick="return LinkClick('section3');">セクション3へ</a><br />
<hr />
<a id="section1">セクション1</a>
<div style="height:300px">コンテンツ</div>
<a id="section2">セクション2</a>
<div style="height:300px">コンテンツ</div>
<a id="section3">セクション3</a>
<div style="height:300px">コンテンツ</div>
<a href="#section1" onclick="return LinkClick('section1');">セクション1へ</a><br />
<a href="#section2" onclick="return LinkClick('section2');">セクション2へ</a><br />
<a href="#section3" onclick="return LinkClick('section3');">セクション3へ</a><br />
<!-- こちらの記述方式でもOK -->
<!--
<a href="#section1" onclick="LinkClick('section1');return false;">セクション1へ</a><br />
<a href="#section2" onclick="LinkClick('section2');return false;">セクション2へ</a><br />
<a href="#section3" onclick="LinkClick('section3');return false;">セクション3へ</a><br />
-->
<hr />
</body>
</html>