ページ内リンクをスムーズにスクロールするJavascriptで以下の条件を満たすものを探しています。


・商用利用可
・移動して止まる際に徐々に減速する(等速移動でない)
・リンク部分にonClickなどを入れないで、単なるページ内リンクの記述だけでいい
・JSのファイルサイズが極端に大きくない

jQueryを使っていても構いません。

回答の条件
  • 1人2回まで
  • 登録:2007/08/04 09:57:23
  • 終了:2007/08/04 20:03:06

ベストアンサー

id:GEN111 No.1

GEN111回答回数472ベストアンサー獲得回数582007/08/04 16:17:56

ポイント100pt

探すのは面倒だったので作ってみましたが、どんなもんでしょう。

IE6、Firefox 2.0.0.6、Opera 9.22 で動作確認しました。


次のスクリプトを inpagelink.js と言う名前で保存

//
// inpagelink.js
//
// ページ内リンク移動
//

//
// 移動
//
function scroll_inpage_link(pos, tpos, spd, rdc) {
  pos += spd ;

  if ((rdc > 0 && pos >= tpos) || (rdc < 0 && pos <= tpos)) {
    document.documentElement.scrollTop = tpos ;
  }
  else {
    document.documentElement.scrollTop = pos ;
    setTimeout('scroll_inpage_link(' + pos + ',' + tpos + ',' + (spd-rdc) + ',' + rdc + ')', 10) ;
  }
}

//
// 移動指定
//
function move_inpage_link(target) {
  tid = target.hash.substr(1, target.hash.length-1) ;
  tobj = document.getElementById(tid) ;
  if (tobj.tagName == 'A') {
    ua = navigator.userAgent ;
    cheight = ua.indexOf('MSIE') >= 0 ? (
      ua.indexOf('MSIE 6') >= 0 ? document.documentElement.clientHeight : document.body.clientHeight
      ) : window.innerHeight ;
    tpos = document.documentElement.scrollHeight - cheight < tobj.offsetTop ? (document.documentElement.scrollHeight - cheight) : tobj.offsetTop ;

    cpos = document.documentElement.scrollTop ;
    rdc = (tpos - cpos) / 5050 ;
    spd = rdc * 100.0001 ;
    timerId = setTimeout('scroll_inpage_link(' + cpos + ',' + tpos + ',' + spd + ',' + rdc + ')', 10) ;
  }
}

//
// 初期化
//
function init_inpage_link() {
  anchors = document.getElementsByTagName('a') ;
  for (i = 0; i < anchors.length; ++i) {
    if (anchors[i].href && anchors[i].href == (document.URL+anchors[i].hash)) {
      anchors[i].onclick = function () {move_inpage_link(this) ; return false ; }
    }
  }
}

呼び出しはこんな感じ

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
  <head>
    <style type="text/css">
      div { margin-bottom : 70% ; }
    </style>

    <script src="inpagelink.js" type="text/javascript"></script>
    <script type="text/javascript">
      onload = function () {
        init_inpage_link() ;
      }
    </script>
  </head>

  <body>
    <div style="margin-bottom:150%;">
      <a id="A">A</a> <a href="#B">To B</a> <a href="#C">To C</a>
    </div>

    <div>
      <a id="B">B</a> <a href="#A">To A</a> <a href="#C">To C</a>
    </div>

    <div>
      <a id="C">C</a> <a href="#A">To A</a> <a href="#B">To B</a>
    </div>
  </body>
</html>

ちょっと減速感は少ないかも。

id:dingding

なんと!

すばらしい。

そんなにすぐ作れるなんて、すごいスキルですね。

動かしてみました。

マーベラス!

2007/08/04 20:02:35
  • id:GEN111
    動作に関しては好みですが、変更案として、
    function scroll_inpage_link(pos, tpos, spd, rdc) {
    if (Math.abs(spd) < Math.abs(rdc)) spd += rdc ; // ← 追加
    pos += spd ;


    move_inpage_link 下の方を次のように変更
    rdc = (tpos - cpos) / 1275 ;
    spd = rdc * 49.8 ;
    setTimeout('scroll_inpage_link(' + cpos + ',' + tpos + ',' + spd + ',' + rdc + ')', 0) ; // 最後を ゼロ にする
  • id:dingding
    度々ありがとうございます。
    試してみたところ、より動きにメリハリがついて、
    とってもいい感じです。ありがとうございます。
  • id:GEN111
    他のページから hoge.html#ID みたいに飛んで来た場合に動作しないと思うのでちょっと手直し


    function init_inpage_link() {
    anchors = document.getElementsByTagName('a') ;
    for (i = 0; i < anchors.length; ++i) {
    if (anchors[i].href && anchors[i].href == (document.URL.replace(/#.*$/,'')+anchors[i].hash)) { // ← 変更
  • id:dingding
    divで3重くらい入れ子になっている中で使ったとき、IEでoffsetTopの値が正確に取れなくて(親タグの位置を基準に見る?)、うまく動かないことがあります。調査中です。
  • id:GEN111
     入れ子状態は分かりませんが、position で relative や absolute を指定したときに正しく動かないことを確認しています (しかもちょっと根が深い問題で解決は難しいかもしれません)。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません