ページトップへスクロール

「▲ページトップへ戻る」をクリックするとスクロールしてページのトップへ移動します。

このサイトの下にある「▲ページトップへ戻る」はすべてスクロールするようになっているのでクリックしてみてください。x座標は変化させずにy座標だけを移動します。

HTML構造

href属性に#introを指定しているのでページ一番上のdivタグにid="intro"を指定しておきます。なくても機能に問題はありませんが、アンカーリンクを付ける時はアンカー先があることが推奨されています。

<a href="#intro">▲ページトップへ戻る</a>

JavaScript

ページを読み込むとすべてのaタグを調べてhref属性の値が#introのものだけonclickにスクロールさせる関数gotoTopを追加します。

urlList関数はリンクを切り取って配列にして返す関数です。アンカー名だけが必要なので返り値の[9]を使います。

function pageTop(){
  var anchorList = document.getElementsByTagName('a');

  for (var i=0, len=anchorList.length; i<len; i++){
    var a = anchorList[i];
    if (a.getAttribute('href').match(/^(.)*\#(.)*/)) {
      var url = urlList(a.getAttribute('href'));
      if (url[9] == "intro") {
        a.onclick = function (){
          gotoTop();
          return false;
        }
      }
    }
  }
  function urlList(url) {
    var r = /^(([^:/?#]+):)?(\/\/([^/?#]*))?([^?#]*)
(\?([^#]*))?(#(.*))?/;
    var a = r.exec (url);

    return a;
  // var url = 'http://example.com/path/to/file?query#fragment';
  // a[2]; 'http'
  // a[4]; 'example.com'
  // a[5]; '/path/to/file'
  // a[7]; 'query'
  // a[9]; 'fragment'
  }
  function gotoTop() {
    var c = {
      easing:100,
      step:30,
      fps:80
    };
    c.ms = Math.floor(1000/c.fps);
    var timerId;
    var param = {
      stepCount:0,
      startY:0,
      endY:0,
      lastY:0
    }
    function move() {
      if (param.stepCount == c.step) {
        // scroll_end
        window.scrollTo(getCurrentX(), param.endY);
      } else if (param.lastY == getCurrentY()) {
        // scroll
        param.stepCount++;
        window.scrollTo(getCurrentX(), getEasingY());
        param.lastY = getEasingY();
        timerId = setTimeout(move, c.ms);
      }
    }
    function getCurrentX() {
      return document.body.scrollLeft 
             || document.documentElement.scrollLeft;
    }
    function getCurrentY() {
      return document.body.scrollTop 
             || document.documentElement.scrollTop;
    }
    function getEasingY() {
      return Math.floor(getEasing(param.startY, param.endY, 
param.stepCount, c.step, c.easing));
    }
    function getEasing(start, end, stepCount, step, easing) {
      var s = stepCount / step;
      return (end - start) * (s + easing / (100 * Math.PI)
 * Math.sin(Math.PI * s)) + start;
    }
    clearTimeout(timerId);
    param.stepCount = 0;
    param.startY = param.lastY = getCurrentY();
    timerId = setTimeout(move, c.ms);
  }
}
window.onload = pageTop;