2009 年 9 月 のアーカイブ

スムーススクロールのソースをメモっておこう。

2009.9.1 火曜日

よくあるヤツだけど、微妙な間隔でリクエストされて、なんか毎回書き起こしてる気がするのでメモ的に。
(ちゃんとソースを管理しておけと)

サンプル

jQueryと、jQuery.easingを使用。

jquery.js
jquery.easing.1.3.js
の2つと下記のスクリプトをロードして、
スクロールにしたいアンカーリンクにclass=”sScroll”の属性を付けておくだけ。

#で始まるリンクを自動で拾う、という形の物が多いけど、
アンカーリンクを全部スクロールにしたくない、とか、
他のスクリプトで使う為にダミーのアンカーリンクを多用してるとか(自分がよくやる)
そんなケースの事を考えて、”sScroll”というクラス名のついた<a>タグだけを対象にした。

IEだと、jQueryのoffset()の値がスクロール位置によって狂うので、IEの時はoffset()の値にスクロール位置を加算して補正。
(offset()って絶対位置を取るんじゃなかったっけ…?)
何故か、divタグに直接borderのスタイルを設定した場合のみ狂う模様?(IEのみ)
レアケースだと思うので上記補正は除去

Operaの場合、”html,body”をanimateすると表示がおかしくなるので、Operaの場合のみ”html”を指定。

jquery.easingでイージングを付けたりした時、ページのスクロール量が足りないと動きがおかしくなるので、
アンカー先のスクロール位置がページのスクロール量を超える場合は調整。

やっつけ感漂う気がするけどこんな感じですかねぇ。

Download: smoothScroll.js
  1. /*
  2. * jQuery SmoothScroll
  3. * Copyright (C) 2009 Hidemaro Mukai(http://www.maro-z.com).
  4. */
  5.  
  6. var span = 1000;
  7. var effect = 'easeOutExpo';
  8.  
  9. $(function() {
  10.     var ua = $.browser;
  11.     $("a.sScroll").click(function() {
  12.         if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') && location.hostname == this.hostname) {
  13.             $(this).blur();
  14.             var t = navigator.appName.match(/Opera/) ? "html" : "html,body";
  15.             $(t).queue([]).stop();
  16.             var $targetElement = $(this.hash);
  17.             var scrollTo = $targetElement.offset().top;
  18.             if (window.scrollMaxY) {
  19.                 var maxScroll = window.scrollMaxY;
  20.             } else {
  21.                 var maxScroll = document.documentElement.scrollHeight - document.documentElement.clientHeight;
  22.             }
  23.             if (scrollTo > maxScroll){
  24.                 scrollTo = maxScroll;
  25.             }
  26.             $(t).animate({ scrollTop: scrollTo }, span, effect);
  27.             return false;
  28.         }
  29.     });
  30. });