サンプル専用ページ

トモタヌキのサンプル集

JavaScriptだけで動かすページ内リンクのスクロール移動のサンプル

この記事に書かれているコードは、以前に作ったスムーズスクロールのスクリプトです。

IEの互換性を重視し、IE8でも動くように意識して書いてます。*1

でも、チェックする環境が無かったので、ちゃんと動くかどうか分からないのですが(笑)

せっかく作ったものので、今回ここで紹介させていただきます。

ちなみに脚注で使われているスクリプトは、このスクリプトではなく、元のページスクリプトです。*2

またイージングも「easeInOutSine」に変更しています。

//スムーズスクロール(ページ内リンク移動)

//スクロール量を取得
function getXScrolled() {
  return (window.pageXOffset !== undefined) ? window.pageXOffset : (document.documentElement || document.body.parentNode || document.body).scrollLeft
}
function getYScrolled() {
  return (window.pageYOffset !== undefined) ? window.pageYOffset : (document.documentElement || document.body.parentNode || document.body).scrollTop
}

//イージング(easeInOutSine)
function easing( t, b, c, d ) {
  return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
};

//ハッシュから対象エレメントを取得する関数
function hashElement( h ){
  var nameORid = decodeURI( h.substr(1) );
  return ( document.getElementsByName( nameORid ).length ) ? document.getElementsByName( nameORid )[0]: document.getElementById( nameORid );
};

//エレメントの位置を取得する関数
function targetPos ( a ) {
  var getPos = a.getBoundingClientRect();
  return getPos.top + getYScrolled();
};

//移動用関数
function pageScroll( te ){
  var posX = getXScrolled();
  var posY = getYScrolled();
  var moved = targetPos( te ) - posY;
  var tween = ( moved > 500 ) ? Math.round( Math.abs( moved ) * 0.01 ) : 5;
  var n = 1;
  (function scrollMoved () {
    if ( moved ) {
      window.scrollTo( posX, easing( n, posY, moved, tween) );
      n ++ ;
      if ( n <= tween ) {
        window.setTimeout( scrollMoved, 20 );
      }
    }
  })();
};

//ページ内リンクにイベント登録
var entryLinks = document.getElementsByTagName('a');
if ( entryLinks.length ) {
  for( var i = 0; entryLinks.length >  i; i++ ) {
    var getATag = entryLinks[i];
    if ( ( getATag.hash ) && ( getATag.href.indexOf( location.href.replace( location.hash, `` ) ) === 0 ) ) {

      if ( getATag.addEventListener ) {
        getATag.addEventListener( 'click', function(e) {
          ( e.preventDefault ) ? e.preventDefault(): e.returnValue = false
          pageScroll( hashElement( e.target.hash ) );
          return false;
        });
      } else {
        getATag.onclick = function(e) {
          ( e.preventDefault) ? e.preventDefault(): e.returnValue = false;
          pageScroll( hashElement( e.target.hash ) );
          return false;
        }
      }

    }
  }
}

動作は簡単ではありますが、確認しています。

このスクリプトの特徴として、ページ内リンクの距離によって、ちょっとスピードが変わるようにしています。

ページ内リンクの移動先が離れていれば離れているほど長く、近ければ短い時間でスクロール移動するようにしています。*3

個人的に、近い距離のページ内リンクがもっさり動くのがイヤで作ってみたのですが……最近では近くても遠くても同じ時間でささっと移動したほうが良いんじゃないかな?と思い、止めました(笑)

今回掲載するにあたり、実はちょっと手を加えています。*4

おかげで、致命的なミスも発見しましたし(笑)

現段階のOSやブラウザ状況でしたら、あまり活躍の場は無いかもしれませんが、何かの参考になるかもしれません。

お役に立てれば幸いです。

元のページにもどる

*1:もっと効率的で上手な書き方がありそうですが…(汗)

*2:今回は「目次」は必要ないかなと思い、設置していません。

*3:ただし近すぎつと速すぎてデフォルトのページ内リンクとほぼ変わらなくなり、スムーズスクロールの意味が無くなります(笑)今回のチェックでそのことに気がついたので、少し修正しました。

*4:改めて見たら、ムダな所が多かったもので(汗)