« StumbleUponとポジティブスパイラル | Main | ブロック要素の中で滑らかスクロールする方法(javascript)2 »

ブロック要素の中で滑らかスクロールする方法(javascript)

ブロック要素の中で滑らかスクロールする方法(javascript)
IE,Firefoxのみで動作確認(IE追加@2006/08/27)

気持ちいいインターフェース。
Scriptaculous.Effects.ScrollTo をHackする方法もあるけれど、重いので自前で。

明日解説するかも。

a
b
c
d
e
f
g
h
[i]
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
[z]








コード:

javascript:
var SmoothScroll = {};
SmoothScroll = {
	targetScrollTop : 0,	// we're gonna make the $(parentid).scrollTop -> targetScrollTop
	dist : 0,
	timer : 0,
	count : 0,
	parentid : 0,
	lastDist : 0,
	//speedStore : [],		// for debug
	options : {},
	defaultOptions : {
		time : 1*1000,	// [ms]
		unit : 50			// [ms]
	},
	scrollTo : function( element, parent, options ){
		this.options.time = this.defaultOptions.time;
		this.options.unit = this.defaultOptions.unit;
		if( options ){
			this.options.time = ( options.time ) ? options.time : this.options.time;
			this.options.unit = ( options.unit ) ? options.unit : this.options.unit;
		}
		clearInterval( this.timer );
		this.parentid = parent;

		this.scrollTopMax = this.$(parent).scrollHeight - this.$(parent).offsetHeight + parseInt(this.$(parent).style.borderTopWidth) + parseInt(this.$(parent).style.borderBottomWidth);

		if( navigator.userAgent.match( "MSIE" ) ){
			this.targetScrollTop = ( element ) ? this.$(element).offsetTop : 0;
		}else{
			var targetOffsetTop = ( element ) ? this.$(element).offsetTop : this.$(parent).offsetTop;
			this.targetScrollTop = targetOffsetTop - this.$(parent).offsetTop;
		}
		this.targetScrollTop = ( this.targetScrollTop > this.scrollTopMax ) ? this.scrollTopMax : this.targetScrollTop;

		this.dist = this.targetScrollTop - this.$(parent).scrollTop;
		this.lastDist = 0;
		this.timer = setInterval('SmoothScroll.update()', this.options.unit );
		this.count = 0;
		//this.speedStore = [];
		this.update();
	},
	update : function(){
		var dist = this.targetScrollTop - this.$(this.parentid).scrollTop;
		var speed = 2 * dist * this.options.unit / ( this.options.time - this.options.unit * this.count );
		//this.speedStore.push( speed );
		speed = ( speed > 0 ) ? Math.ceil( speed ) : Math.floor( speed );
		if( Math.abs(dist) <= Math.abs(speed) ){
			// got there
			clearInterval( this.timer );
			this.$(this.parentid).scrollTop = this.targetScrollTop;
			return;
		}else if( this.lastDist == dist ){
			// stuck
			clearInterval( this.timer );
			this.$(this.parentid).scrollTop = this.targetScrollTop;
			return;
		}
		var scrollTop = this.$(this.parentid).scrollTop + speed;
		this.$(this.parentid).scrollTop = scrollTop;
		this.lastDist = dist;
		this.count++;
		if( this.count == this.options.time / this.options.unit ){
			// timeout
			clearInterval( this.timer );
			this.$(this.parentid).scrollTop = this.targetScrollTop;
		}
	},
	$ : function(id) {
		return document.getElementById(id);
	}
}
function gototop(){
	document.getElementById('scroll20060827').scrollTop = 0;
}

html:
<div id="scroll20060827" style="width: 100px; height: 100px; overflow-y: scroll; border: 2px black dotted;">
a<br />b<br />c<br />d<br />e<br />f<br />g<br />h<br />
<span id="t20060827i" style="color: red"><b>[i]</b><br />
</span>j<br />k<br />l<br />m<br />n<br />o<br />p<br />q<br />r<br />s<br />t<br />u<br />v<br />w<br />x<br />y<br /><span id="t20060827z" style="color: blue"><b>[z]</b></span><br />
</div>
<input type="button" value="go to top (normal)" onclick="gototop();"/>
<input type="button" value="go to top smoothly" onclick="SmoothScroll.scrollTo(0,'scroll20060827');"/>
<input type="button" value="go to [i] smoothly" onclick="SmoothScroll.scrollTo('t20060827i','scroll20060827');"/>
<input type="button" value="go to [z] smoothly" onclick="SmoothScroll.scrollTo('t20060827z','scroll20060827');"/>
<input type="button" value="go to [i] smoothly, but FAST" onclick="SmoothScroll.scrollTo('t20060827i','scroll20060827',{time: 500});"/>
<input type="button" value="go to [z] smoothly, but FAST" onclick="SmoothScroll.scrollTo('t20060827z','scroll20060827',{time: 500});"/>
<input type="button" value="go to [i] smoothly, but SLOW" onclick="SmoothScroll.scrollTo('t20060827i','scroll20060827',{time: 2000});"/>
<input type="button" value="go to [z] smoothly, but SLOW" onclick="SmoothScroll.scrollTo('t20060827z','scroll20060827',{time: 2000});"/>

TrackBack

このエントリーのTrackBackURL:
http://slightlyblue.com/cgi/mt/mt-tb.cgi/654

この一覧は、次のエントリーを参照しています: ブロック要素の中で滑らかスクロールする方法(javascript):

» ブロック要素の中で滑らかスクロールする方法(javascript)2 from blog@slightlyblue
昨日の ブロック要素の中で滑らかスクロールする方法(javascript) は... [詳しくはこちら]

コメントを投稿

同カテゴリ[DEVELOP]のエントリー

最近のトラックバック