jstarted.com
JavaScript/HTML/CSSのノウハウや覚書を掲載するブログ
2013.8. 2

スクロールするとセクションごとに違う演出が起こる(セクション高さ固定)

Category:

スクロールするとセクションごとに違う演出が起こる(全画面版)」を書いたばかりですが、セクションの高さを全画面サイズまで広げず、固定した状態で同じような動作をさせたい場合のコードも書きました。上述の記事のマイナーチェンジです。

htmlは前回と同様なので省略します。javascriptは以下。

var	win = $(window),
	win_w = win.width(),
	win_h = win.height(),
	body,
	body_h,
	sct = [],
	sct_cls,
	scrl_tp = 0,
	sct_shift = Math.floor( win_h / 5 * 3 ), // sectionのアニメ開始位置のズレ値
	nv,
	nv_li,
	nv_prv,
	nv_nxt;

// 呼び出し関数
var sct_scrl = function(){
	sct_arr_set();
	sct_scrl_set();
};

// 各セクションを元にオブジェクトを作成
var sct_arr_set = function(){
	sct_cls.each(function(indx){
		sct[indx] = {
			id : $(this).attr("id"),
			top : $(this).offset().top,
			flag : false,
			navi : '',
			focus : false
		};
	});

	// ナビゲーションをセクションのオブジェクトのnaviに代入
	// セクションとナビの順番が一意である必要がある
	$('li:not(".preview, .next")', nv).each(function(indx){
		sct[indx].navi = $(this);
	});
};

// セクションのオブジェクトの値(id, top)を元に、
// セクションごとにそれぞれ動作が発生するタイミングを設定
var sct_scrl_set = function(){
	sct_cls.each(function(indx){
		sct_evnt(indx,  sct[indx].id, sct[indx].top);
	});
};

var sct_evnt = function(indx, sct_id, sct_top){
	var sct_evnt_set = function(){
		var focus_off = function(indx){
			nv_li.removeClass('current');
			if( sct[indx + 1] !== undefined ){
				sct[indx + 1].focus = false;
				nv_nxt.attr('href', '#' + sct[indx + 1].id);
			}
			if( sct[indx - 1] !== undefined ){
				sct[indx - 1].focus = false;
				nv_prv.attr('href', '#' + sct[indx - 1].id);
			}
			sct[indx].navi.addClass('current');
			sct[indx].focus = true;
		};

		// 各セクションごとの演出の関数を設定
		// 1つずつ手動で記載する必要アリ
		if( scrl_tp >= sct_top - sct_shift && sct[indx].flag === false ){
			sct[indx].flag = true;
			switch (sct_id){
				case sct[0].id:
					anm_no0();
					break;
				case sct[1].id:
					anm_no1();
					break;
				case sct[2].id:
					anm_no2();
					break;
				case sct[3].id:
					anm_no3();
					break;
			}
		}

		// セクションがフォーカスされたタイミング+
		// フォーカスしているセクションに変更があったかどうかを判定し、
		// フォーカス外し関数を実行
		if( scrl_tp >= sct_top - sct_shift && sct[indx].focus === false ){
			if( sct[indx - 1] === undefined && scrl_tp < sct[indx + 1].top ){
				focus_off(indx);
			} else if( sct[indx + 1] === undefined && ( scrl_tp == body.height() - win.height() || scrl_tp >= sct[indx].top ) ){
				focus_off(indx);
			} else if( scrl_tp >= sct[indx].top && scrl_tp < sct[indx + 1].top ){
				focus_off(indx);
			}
		}
	};

	// ロード直後、既にスクロールされているセクションの演出を実行
	sct_evnt_set();

	// スクロールイベントに、セクションごとの演出判定を代入
	win.scroll(function(){
		sct_evnt_set();
	});
};

// 各セクションごと具体的な動作
var anm_no0 = function(){
	// ...
};

var anm_no1 = function(){
	// ...
};

var anm_no2 = function(){
	// ...
};

var anm_no3 = function(){
	// ...
};

win.resize(function(){
	win_w = win.width();
	win_h = win.height();
	sct_arr_set();
	sct_scrl_set();
});

win.scroll(function(){
	scrl_tp = win.scrollTop();
});

$(document).ready(function(){
	// ページ読み込み完了後にDOM取得
	body = $('body');
	body_h = body.height();
	sct_cls = $('.section');
	nv = $('#navi');
	nv_li = $('li', nv);
	nv_prv = $('li.preview a', nv);
	nv_nxt = $('li.next a', nv);

	sct_scrl();
});

動作のサンプルはこちら
スクロールするとセクションごとに違う演出が起こる(セクション高さ固定) - js do it

jstarted.comはamazon.co.jpを宣伝しリンクすることによってサイトが紹介料を
獲得できる手段を提供することを目的に設定されたアフィリエイト宣伝プログラムである、
Amazonアソシエイト・プログラムの参加者です。

クリエイティブ・コモンズ・ライセンス
jstarted.com by yoichi kobayashi is licensed under a Creative Commons 表示 3.0 非移植 License.