jQueryのトグルアップ・トグルダウンを利用して、サイトに動きを付けてみた

each関数を使って、JavaScriptを簡略化しました。(2009.06.01)

というわけで、僕のポートフォリオサイト「スカイラブデザイン」がちょっとだけ変わりました。
そのキャプチャが以下。

「スカイラブデザイン」のサイトキャプチャ

コンテンツを変えたワケでもないし、基本デザインも変わってないんだけど、jQueryを使って少し動きを付けてみた。

実際にサイトを触ってもらえると分かると思うけど、ラベルをクリックすると、対応するコンテンツが現れたり消えたりするという、いわゆるトグルアクションをjQueryで実装してみただけ。

安易にjQueryに頼りたくないなあと思って、今まで避けてきたけど、使い方くらい知っとこうと思って今回自分のサイトで試してみた。

jQueryのトグルアクションに苦戦。

jQueryを使い慣れてる人なら、30分もかけず、このくらいの動きを実装できると思うけど、jQuery以前にJavaScriptの基本もあやふやな僕は、丸1日くらい悩んでしまった。

悩んで実装した結果を備忘録としてメモ書き。

HTMLのコード

jQueryの前に、まずはHTMLのコードから。(簡略化してます)

<html>
<body>
<div id="container">
	<div id="header">ヘッダー</div>
	<ul id="gnav">
		<li id="gnav01"><a href="#box01">グローバルナビ1</a></li>
		<li id="gnav02"><a href="#box02">グローバルナビ2</a></li>
		<li id="gnav03"><a href="#box03">グローバルナビ3</a></li>
	</ul>
	<div id="contents">
		<div id="contentsMain">
			<div id="box01">コンテンツ1</div>
			<div id="box02">コンテンツ2</div>
			<div id="box03">コンテンツ3</div>
		</div>
	</div>
	<div id="footer">フッター</div>
</div>
</body>
</html>

ヘッダがあってナビがあってフッターがあって、その間にコンテンツがあるという典型的なHTMLソース。ここまでは問題なかったのだが・・・。

jQueryでやったこと(概要)

jQueryでどんな操作をしたのか、コードではなく、まずはフローとして書いてみる。

1) コンテンツエリア(#contents)の表示をオフに。

CSSで非表示にするとSEO的にあれなので、JavaScript側でオフにする。

2) 全体(#container)を上下中央揃えに。

ウインドウの大きさと、コンテンツエリアを除いた全体の高さを算出し、positionを使って上下中央の位置に揃える。

3) グローバルナビ(#gnav)のクリックに応じて、対応するコンテンツを表示(トグルダウン)。

コンテンツエリアをいったん全部表示し、必要ないコンテンツの表示はオフにする。それと同時に、コンテンツの高さを算出しトグルアクションに備える。

4) トグルダウンにスムーズな動きを付ける。

3)で算出したコンテンツの高さを元に、上下中央揃えを保ったままスムーズにトグルダウンさせる。ただし、ウインドウからコンテンツがあふれる場合は、ウインドウの上辺基準に変更する。

5) グローバルナビを再度クリックした際のトグルアップ処理。

トグルアップは上記の3),4)の逆の処理を行う。で算出したコンテンツの高さを元に、上下中央揃えを保ったままスムーズにトグルダウンさせる。

6) ウインドウサイズがリサイズされた際の処理。

ウインドウを拡大・縮小した場合、上下中央揃えの処理を再度行う。

以上1)~6)の処理をjQueryで行うことにした。この辺から既に試行錯誤が始まっていた・・・。

jQueryの実装

下記のコードそのまんま。


$(function(){//$(document).ready()の短縮形

	/****** 初期設定 ******/
	var content = $('#contents');
	var contain = $('#container');
	var contmain = $('#contentsMain');
	var header = $('#header');
	var gnav = $('#gnav');
	var footer = $('#footer');
	content.css('display','none');
	var opPos;
	var clPos = clPositon();
	contain.css('top',clPos);

	/****** トリガー設定用 ******/
	var gnavs = gnav.find('li[id^=gnav]');//id=gnav**が付与されたli要素を抽出
	gnavs.each(function(){//gnavsのすべての要素に対して繰り返し処理実施
		var selector = $(this).find("a").attr('href');//gnavsの各a要素のhref属性#hogeを取得
		var box = $(selector);
		$(this).toggle(
			function(){//open
				contmain.empty();
				contmain.append(box);
				opPos = opPositon();
				toggleDownAction(content,contain,opPos);

			},
			function(){//close
				clPos = clPositon();
				toggleUpAction(content,contain,clPos);
			}
		)
	});

	/****** トグルアクション関数 ******/

	//トグルダウン(open)
	function toggleDownAction(cc,ct,op){
		cc.show();
		ct.animate(
			{top:op}
		)
	}
	//トグルアップ(close)
	function toggleUpAction(cc,ct,cp){
		cc.hide();
		ct.animate(
			{top:cp}
		)
	}

	/****** 位置算出用関数 ******/

	//オープン状態に取る位置を算出
	function opPositon(){
		getSize();
		cMargin = Math.round((docHeight - 60 - hdHeight - gnHeight - ftHeight - ctHeight)/2);
		if(docHeight < ctHeight){cMargin=0;}
		if(cMargin < 0){cMargin=0;}
		return cMargin;
	}

	//クローズ状態に取る位置を算出
	function clPositon(){
		getSize();
		nMargin = Math.round((docHeight - 100 - hdHeight - gnHeight - ftHeight)/2);
		if(nMargin < 0){nMargin=0;}
		return nMargin;
	}

	//各DOM要素のサイズ取得
	function getSize(){
		docHeight = $(window).height();
		hdHeight = header.height();
		gnHeight = gnav.height();
		ftHeight = footer.height();
		ctHeight = content.height();
		cnHeight = contain.height();
	}

	//ウインドウリサイズ時の処理
	$(window).resize(function(){
		if(content.css('display')=='none'){
			currentPos = clPositon();
		} else {
			currentPos = opPositon();
		}
		contain.css('top',currentPos);
	})
})

ということで、とりあえず実装できたんだけど、もう全然ダメ、俺。

jQueryの書き方がどうのこうのよりも、JavaScriptの変数の扱いが途中でよく分からなくなり、勉強不足を身にしみて感じた今回のプチリニューアル。

これを機会にオライリーのサイの本で、基礎から勉強しなおそうと思った冬の日の週末でした。

JavaScript 第5版JavaScript 第5版
村上 列

オライリー・ジャパン 2007-08-14
売り上げランキング : 11884
おすすめ平均

Amazonで詳しく見る
by G-Tools