WEBOPIXEL

jQueryで長いページの区切り(セクション)ごとに背景を変化させる

Posted: 2011.11.07 / Category: javascript / Tag: ,

最近は一ページに内容を詰め込んだ縦長のページが増えてきましたね。
そこでスクロールすると区切り(セクション)ごとに背景が変化したら、面白いのではないのかと思いましたのでやってみました。

Sponsored Link

DEMO

一応ie6とかでも動きますが重いですね。

demo

html

sectionはhtml5ではなくdivにclassでマークアップした昔ながらの形式にしました。

html

	<div class="section">
		<h2>Section0</h2>
		<p>
			ここは0番目のコンテンツです。
		</p>
	</div>
	<div class="section">
		<h2>Section1</h2>
		<p>
			ここは1番目のコンテンツです。
		</p>
	</div>
	<div class="section">
		<h2>Section2</h2>
		<p>
			ここは2番目のコンテンツです。
		</p>
	</div>
	・・・
	

bodyの背景色を切り替えるだけの簡単な例

背景が単色ならbodyの「background-color」を切り替えるのが一番単純だと思います。
カラーのアニメーションをするには「jquery.color.js」を使用すると簡単です。

jquery.color.js

やることは最初に各sectionの位置を配列に入れます。

スクロールしたら現在の位置「$(window).scrollTop()」と先ほど作成した各sectionの配列を比較して、多かったら背景を変更します。

わけのわからない図になってますね。
コードは次のようになります。

javascript

	$(function() {
		var pageTop = $('html, body');
		//各sectionの位置を入れる配列
		var secTopArr = new Array();
		//現在の番号
		var current = -1;
		//カラー設定の配列
		var bgColor = new Array('#FFCC00','#33CCFF', '#CCCC99', '#33CC99', '#FF99CC');
		//各sectionの位置を入れる
		$('div.section').each(function (i) {
			secTopArr[i] = $(this).offset().top;
		});
		//スクロールイベント
		$(window).scroll(function () {
			for (var i = secTopArr.length-1; i>=0; i--) {
				if ($(window).scrollTop() > secTopArr[i] - 100) {
					chengeBG(i);
					break;
				}
			}
		});
		//背景変更
		function chengeBG(secNum) {
			if (secNum != current) {
				current = secNum;
				$('body').stop().animate({backgroundColor: bgColor[current]},200);
			}
		}
	});
	
13~20行目
スクロールイベントでは配列の最後からループさせ、現在の位置「$(window).scrollTop()」がセクションの位置「secTopArr[i] 」より大きかっら、背景を切り替える「chengeBG(i)」を実行します。
「-100」の部分はピッタリで切り替わるとあれなので、ちょっと前から切り替えてます。
内容によって調節してください。
23~28行目
ここで背景色を変更しています。
次の番号「secNum」が、現在の番号「current」でなかった場合のみ処理します。

背景に画像を使用する場合

背景に画像を使用したい場合バックグラウンドのアニメーションは使えないので新たに要素を追加することになります。
まずはセクションの数だけcssで背景画像を指定します。

css

	#bg0, #bg1, #bg2, #bg3, #bg4 {
		height: 100%;
		width: 100%;
		position: absolute;
		top: 0;
		left: 0;
		z-index: -1;
	}
	#bg0 {
		background: url(img/bg0.gif);
	}
	#bg1 {
		background: url(img/bg1.gif);
	}
	#bg2 {
		background: url(img/bg2.gif);
	}
	#bg3 {
		background: url(img/bg3.gif);
	}
	#bg4 {
		background: url(img/bg4.gif);
	}
	

javascript

	$(function() {
		var secTopArr = new Array();
		var moveFlug = false;
		var bgImg = new Array('img/bg0.gif','img/bg1.gif', 'img/bg2.gif', 'img/bg3.gif', 'img/bg4.gif');
		var allHeight = $('body').outerHeight(true);
		$('div.section').each(function (i) {
			secTopArr[i] = $(this).offset().top;
		});
		var current = -1;
		$(window).scroll(function () {
			for (var i = secTopArr.length-1; i>=0; i--) {
				if ($(window).scrollTop() > secTopArr[i] - 100) {
					chengeBG(i);
					break;
				}
			}
		});
		//背景変更
		function chengeBG(secNum) {
				if (secNum != current) {
					$('body').css('background', 'url('+bgImg[secNum]+')');
					$('#bg'+current)
						.fadeOut(500, function(){
							$(this).remove();
						});
					$('#wrap').append('<div id="bg'+secNum+'"></div>');
					$('#bg'+secNum)
						.height(allHeight)
						.css('display','none')
						.fadeIn(500);
					current = secNum;
				}
		}
	});
	
18~31行目
おもに変更したのはこのあたりです。
cssで指定した「#bg」を追加してfadeOutでアニメーションしてます。
追加していくだけではあまりよろしくないので、前の「#bg」は削除しましょう。
「$(‘body’)」にcssと同じ画像指定しているところとかあまりよくないかもしれませんが、こんな感じに落ち着きました。

スルスルっとスクロールするナビゲーション

最後にスルスルっとスクロールするナビゲーションボタンを作成します。
基本的にはそのまま実装しても問題ないのですが、上から一番下にスクロールすると背景切り替えを全て実行されるのでちょっと気になります。

ナビゲーション部分のhtmlは次のようにしてます。

html

	<ul id="nav">
		<li><a href="#s0">SECTION 0</a></li>
		<li><a href="#s1">SECTION 1</a></li>
		<li><a href="#s2">SECTION 2</a></li>
		<li><a href="#s3">SECTION 3</a></li>
		<li><a href="#s4">SECTION 4</a></li>
	</ul>
	

前述のコードの19行目を次のように変更します。

javascript

	if (secNum != current && moveFlug == false) {
	

あらたに追加するコードです。

javascript

	$('#nav li').click(function(){
		moveFlug = true;
		var getNum = $(this).index();
		var secTop = $('.section').eq(getNum).offset().top;
		$('html,body').animate({ scrollTop: secTop }, 'slow', function() {
			moveFlug = false;
			chengeBG(getNum);
		});
		return false;
     });
	

COMMENTS

テツ 2012-06-10 15:39 

いつも参考にさせて頂いています。

質問なんですが、「背景に画像を使用する場合」
この画像を全画面表示する事はできますでしょうか?

webOpixel 2012-06-11 16:06 

css3なら「background-size:cover」でできたと思います。
jQueryなら下記が参考になるかもしれません。
http://www.webopixel.net/javascript/203.html

テツ 2012-06-16 01:02 

ご回答有り難うございます。

現在、css3「background-size:cover」で対応させています。
ですが、IEだと未対応のため、上記のjavascriptに全画面表示用のコードを追加するとできるのかと思い質問させて頂きました。

参考にさせて頂きます。

dai 2014-07-11 02:21 

いつも参考にさせていただいてます。

上記テツさんと同じような質問なのですが
cssで画面サイズいっぱいに画像を表示させようと思っております。

デモhtmlを参考に、bodyと#bg0~#bg4に
>>background: url(img/画像名) no-repeat center center fixed;
>>background-size: cover;
と記載したところ、以下のような現象が起きてしまったので
どこに問題があるのか、ご指摘していただけたらと思い書き込みさせていただきました。

1)画面を開く→0番目のコンテンツへスクロール
1度だけフェードインが発生する。
(それ以降ページ上部に戻り、再度0番目コンテンツへスクロールしてもフェードインは発生しない)
フェードイン時、背景画像がリピートされた状態で一瞬表示する。

2)スクロールし、各コンテンツの背景画像切り替え時
フェードイン時、背景画像がリピートされた状態で一瞬表示する

解決策またはcssの記述ミスなどありましたら
ご指摘いただけますでしょうか?
よろしくお願いいたします。

webOpixel 2014-07-11 16:07 

cssのbodyのところにもcoverなどbackgroundの設定をして、
jsの「chengeBG」関数の「$(‘body’).css(‘background’」を
「$(‘body’).css(‘background-image’」に変更してみてください。

これを作ったのがかなり前なのであまりいい動きをしないかもしれませんが、とりあえず。。

最近はスクロール関係のプラグインも色々とありますので、そういうのを探してみる方をオススメします^^;

dai 2014-07-11 17:28 

お返事、ありがとうございます!

関数を変えた所、Win環境では、まだ未確認ですがMac環境で
質問で書かせていただいた現象が全て起きなくなりました!

他プラグインも、いろいろ探しているのですが
スクリプトの勉強不足もあり、なるべくシンプルで使いやすそうな
参考サイトを探しておりました(汗。

勉強もかねて、いろいろ試したいと思います。
ありがとうございました!

LEAVE A REPLY

コードを書く場合は<pre>で囲んでください。