POPSブログ

jQuery slideToggle縦並びアコーディオン

354

  Category:  jquery2015/04/16 pops 

toggleクリック関数を使用しないアコーディオン Accordion(clickタイプ)で、slideToggle関数を使用して「単純効率化」したものです。toggle()を使用していませんので、jquery-1.9系、jquery-2.0系でも動作します。

 

jQuery slideToggle縦並びアコーディオンMENUテスト

以前のslideToggle縦並びアコーディオンは少し非効率でしたので、単純効率化したものです。siblings() 形式で組んでいますから簡素なスクリプト記述が特徴です。今回はブロックの中を ul li で記述してみました。

 

基本的には以下のページの「アコーディオン」JSを修正したものです。

【参照】当方の記事: jQuery toggleクリック関数を使用しないアコーディオン

 

● [ タイトル要素を指定してアコーディオン化する簡単な方法 ] をページ最終段に追加しました。2015/04/21

 

 

slideToggleサンプル

nisemono

 

slideToggleアコーディオン説明のデモです。「MENUタイトル」をクリック ください。


accordion40

開いたままのタイプで連動せず独立して開閉します。このページはjquery-1.6.4に成ります。

slideToggle切り替え

MENUブロック1

MENUブロック2

MENUブロック3


タイプ別の各種デモ


● デモページは [ jqury-1.9 ] で動作しています。HTML、CSS、JS、は「デモ」ページに掲載しています。

DEMO-012



 

accordion40のHTML

サンプルと同様に記述して使用します。これはブロックの中を「ul」「li」で記述しています。


<div id="accordion-40" class="accordion-box">
	<h3>MENUブロック1</h3>
	<div class="accordion-block">
		<ul>
		<li><a href="javascript:void(0);">リンク</a></li>
		<li><a href="javascript:void(0);">リンク</a></li>
		<li><a href="javascript:void(0);">リンク</a></li>
		</ul>
	</div>
	<h3>MENUブロック2</h3>
	<div class="accordion-block">
		<ul>
		<li><a href="javascript:void(0);">リンク</a></li>
		<li><a href="javascript:void(0);">リンク</a></li>
		<li><a href="javascript:void(0);">リンク</a></li>
		</ul>
	</div>
	<h3>MENUブロック3</h3>
	<div class="accordion-block">
		<ul>
		<li><a href="javascript:void(0);">リンク</a></li>
		<li><a href="javascript:void(0);">リンク</a></li>
		<li><a href="javascript:void(0);">リンク</a></li>
		</ul>
	</div>
</div>

accordion40のJS

サンプルと同様に記述して使用します。ID名、クラス名を変更した場合はJS側も変更ください。
保存名は任意です。


//Accordion
//accordion-40
(function($){

	$(function(){

		//速度
		var slide_speed=400;
		//active要素を指定して開く
		var no=0;

		//----------------------------------
		var accordionItem=$('#accordion-40');//Item

		//MENUブロック一旦非表示
		accordionItem.find('.accordion-block').hide();
		//active要素を指定して開く
		accordionItem.find('h3').eq(no).addClass('active').next('div').show();

		//click-action
		accordionItem.find('h3').click(function() {

			//hit判定クラス
			$(this).toggleClass("active");
			var slideItem=$(this).next('div');

			//hit分岐処理
			if ($(this).hasClass('active')) {

				//hitクラスを開く
				slideItem.slideToggle(slide_speed);

			} else {

				//hitクラスを閉じる
				slideItem.slideToggle(slide_speed);
			}

		});

		//hover-toggle
		accordionItem.find('h3').hover(function () {

			//toggle hoveredクラス
			$(this).toggleClass('hovered');

		});

	});

})(jQuery);

CSS

これは一例です。ページのCSSによってはレイアウトが狂うことが有りますので、修正ください。


/*accordion-001c ul ii 用*/
.accordion-box {
width:200px;
height:auto;
margin:0;
padding:1px 0;
text-align:left;
border-bottom:1px #EEEEEE solid;
background-color:#EEEEEE;
}

.accordion-box h3 {
width:188px;
height:20px;
margin:1px 0 0 1px;
padding:2px 0 0 10px;
line-height:20px;
color:#FFFFFF;
font-size:12px;
background:url(/main/images/arrow_13.gif) no-repeat;
background-color:#BBBBBB;
background-position:right 0px;
cursor:pointer;
}
/* active */
.accordion-box h3.active {
background-position:right -21px;
}
/* hovered */
.accordion-box h3.hovered {
background-color:#DAA520;
}

.accordion-box .accordion-block {
display:block;
width:198px;
margin:1px 0 0 1px;
padding:0;
background-color:#FFFFFF;
}

.accordion-box .accordion-block ul {
display:inline;
list-style:none;
margin:0;
padding:0;
}
.accordion-box .accordion-block ul li{
list-style:none;
width:190px;
height:16px;
margin-left:5px;
padding:0;
border-bottom:1px #EEEEEE solid;
line-height:16px;
font-size:12px;
color:#555555;
}

.accordion-box .accordion-block ul li a {
text-decoration:none;
color:#BBBBBB;
}
/* text-shadow*/
.textshadow{
text-shadow:1px 1px 3px #000000;
}


 

簡単な説明

色々な書き方はありますが、一番簡素なJSは上記の如くであり、下記のような処理を行います。


JSの動作

slideToggle()、toggleClass()、hasClass()、を利用します。基本動作は次の様になります。


1. 最初、アコーディオンさせるブロックの要素を.hide()で非表示にします。
2. タイトルをクリックすれば、toggleClass()でクラス名「active」を交互に切り変えます。
3. slideItemでスライドするブロックをオブジェクト保存します。
4. 閉じている要素のタイトルを押せば、hasClass('active')は「true」で、最初のslideToggle()を実行してブロックを表示します。
(動作を変える場合はこの最初の処理をアレンジすれば色々と変化を付ける事が出来ます)
5. タイトルが概に「active」で開いているならば、タイトルを押せば、hasClass('active')は「false」になり、次のslideToggle()を実行してブロックを非表示にします。
6. slideToggle()はスライド処理になります。ここのサンプルは全てスライドです。
7. fadeToggle()はフエード処理になりますが、ここでは合わないので利用していません。
8. 詳しくはそれぞれの動きに対応する、デモのJSを見てください。


連動形の処理

開閉の状態により4種類を作ってあります。動作はデモを参照ください。


1. 上のデモの様に連動しないタイプ。再度クリックしないと閉じない。
2. 最初に開いてから、他を閉じるタイプ。伸縮が激しい。
3. 他を閉じてから開くタイプ。伸縮はさほどではない。
4. 同時に開閉するタイプ。伸縮が少なくなるため一番見易いと思います。
5. アコーディオンDIVブロックの中の記述は自由です。


タイプ別の各種デモ


● デモページは [ jqury-1.9 ] で動作しています。HTML、CSS、JS、は「デモ」ページに掲載しています。

DEMO-012



CSS

基本的に個人の好みで作ります。デモページにサンプルのCSSを掲載しています。
昨今は、以前のブラウザなどが排除され、モダンブラウザのみ対応が増えていますのでCSSの記述も幾分楽になったと思います。


jQueryオブジェクトに保存して実行を早くする

下記の様にjQueryオブジェクトに保存すれば、若干実行速度が上がります。



var accordionItem=$('#accordion-40');
var slideItem=$(this).next('div');

active要素を指定して開く

要素の番号を入れます。最初は0です。
開かない場合は、下記の様に実行しないようにチェックします。



//active要素を指定して開く
//accordionItem.find('h3').eq(no).addClass('active').next('div').show();

タイトルホーバーでの変化

下記の様にJSで実行しています。不要な場合は削除ください。(当然、CSSのみでも処理できます)
CSSの変更で、色を変えたりは自由です。



//hover-toggle
accordionItem.find('h3').hover(function () {

	//toggle hoveredクラス
	$(this).toggleClass('hovered');

});

閉じてから開くタイプ

他の処理は単純化できるが、閉じてから開くタイプがなかなか面倒である。
策としてdelay処理でごまかせるので、以下の様にした。「開いてから閉じる」処理に delay() を加えただけです。
(slideToggleのみで処理出来る、不思議)



//開いてから閉じる
slideItem.slideToggle(slide_speed).siblings('div:visible').slideToggle(slide_speed,function() {
	$(this).prev('h3').toggleClass("active");
});

● click-action の部分を掲示すれば、


//click-action
accordItem.find('h3').click(function() {

	//hit判定クラス
	$(this).toggleClass("active");
	var slideItem=$(this).next('div');

	//hit分岐処理
	if ($(this).hasClass('active')) {

		//閉じてからhitクラスを開く/delay処理する
		slideItem.delay(slide_speed).slideToggle(slide_speed).siblings('div:visible').slideToggle(slide_speed,function() {
			$(this).prev('h3').toggleClass("active");
		});

	} else {

		//hitクラスを閉じる
		slideItem.slideToggle(slide_speed);

	}

});

● delay()処理をしないならば、
本来、時間差を付けないと意味がないので、実際には先に slideUp() させての次の処理になる。

個人により判定方法、書き方など違いますので、一例です。


//click-action
accordItem.find('h3').click(function() {

	//hit判定クラス
	$(this).toggleClass("active");
	var slideItem=$(this).next('div');

	//hit分岐処理
	if ($(this).hasClass('active')) {

		var siblingsItem=slideItem.siblings('div:visible');
		if(siblingsItem.length){
			siblingsItem.slideUp(slide_speed,function() {
				siblingsItem.prev('h3').toggleClass("active");
				slideItem.slideToggle(slide_speed);
			});

		} else {
			slideItem.slideToggle(slide_speed);
		}

	}
	if (!$(this).hasClass('active')) {

		//hitクラスを閉じる
		slideItem.slideToggle(slide_speed);

	}

});

整理すると、以下の様に短くできる。(但し、slideToggleのみでの処理はできない)


//click-action
accordItem.find('h3').click(function() {

	//hit判定クラス
	$(this).toggleClass("active");
	var slideItem=$(this).next('div');

	//hit分岐処理
	var siblingsItem=slideItem.siblings('div:visible');
	//先に閉じるブロックがあれば閉じる
	if(siblingsItem.length){
		siblingsItem.slideUp(slide_speed,function() {
			siblingsItem.prev('h3').toggleClass("active");
			slideItem.slideToggle(slide_speed);
		});

	} else {
		//無ければtoggle
		slideItem.slideToggle(slide_speed);
	}

});

siblingsItemの判定

上記の、if(siblingsItem) {......} 判定で「は開いている要素」が無くとも一律に true に成るのでlengthで判定した。



これで判定できない
if(siblingsItem){.....}

こちらなら判定できる
if(siblingsItem.length){.....}

モット良い方法が見つかった、「同時開閉」などを後日「次のページ」で考えて見ます。


 

タイトル要素を指定してアコーディオン化する簡単な方法


既存のCMSページなどで、主に「サイドバー」等をアコーディオン化するためのものです。また記事中のコンテンツなどの処理にも応用できます。

非常に簡単に出来るのですが、これには定番の構成 ( h3 ul li 等の順序 ) になっていることが条件になります。
例えばタイトルを「クリック」して下位の「ul」を開く場合です。

●「開閉交互」サンプル、「タイトル」を「クリック」して下さい。開閉します。



HTML

「タイトル」の下に必ず「ul」または「dl」がある事が条件になります。ほとんど「ul」です。

ほとんどのCMSは標準で次の様な構成の場合が多い。h ul li の作りがネストしている。最近は、widget形式のサイドバーが多くdivが2重3重になっているものも多いので「開閉交互」以外のアコーディオン形式にするのは困難です。

現実には、タイトルは h1-h4 と幅広い。タイトルに個別のID、クラスが設定されていれば理想的です。



<div id="x-block" class="x-block-title">
	<h3>タイトル1</h3>
	<ul>
	<li><a href="javascript:void(0);">リンク1</a></li>
	<li><a href="javascript:void(0);">リンク2</a></li>
	<li><a href="javascript:void(0);">リンク3</a></li>
	<li><a href="javascript:void(0);">リンク4</a></li>
	<li><a href="javascript:void(0);">リンク5</a></li>
	<li><a href="javascript:void(0);">リンク6</a></li>
	</ul>
</div>

JS

スライドの時間は、200-600ミリ秒が標準。ページの構成次第では、ID名、h要素、ul要素等は変更が可能になります。
要素走査の次第では書き方が違いますが、ここではタイトルが基準になりますので、正確にタイトル要素を指定できれば良い。ページの構成によって違いがでますから多少jQueryの知識が必要となります。


(function($){
	$(function(){
		$('#x-block').find('h3').next('ul').hide();
		$('#x-block').find('h3').click(function(){
			$(this).next('ul').slideToggle(600);
		});
	});
})(jQuery);

ID指定、クラス指定であればモット簡単です。直接指定すればよい。複数のブロックのアコーディオン化が容易になります。上下開閉の slideToggle() が一番綺麗です。


	$(function(){
		$('#タイトルID名').next('ul').hide();
		$('#タイトルID名').click(function(){
			$(this).next('ul').slideToggle(600);
		});
	});

● .next()で記述すれば、ul dl div でも指定できます。

動作サンプルでは、ページでレイアウトが壊れ難いので dl dt 記述が多い。実際のCMSなどでは ul li が使用されています。リストの必要でない場所はdiv構成が多いようです。


	$(function(){
		$('#x-block').find('h3').next().hide();
		$('#x-block').find('h3').click(function(){
			$(this).next().slideToggle(600);
		});
	});

● タイトルにクラスを追加するのも簡単です。
下記の例では「active」クラスを追加します。アコーディオンを開いた場合に有効になります。
事前に、タイトル要素に「xxxxx-accordion」クラス(名前は自由)を書き込んでおきます。複数のコンテンツをアコーディオン化できる例です。毎度読み込む、common.js などに記載すれば結構便利と思います。



<h3 class="xxxxx-accordion">タイトル</h3>


	$(function(){
		$('.xxxxx-accordion').next().hide();
		$('.xxxxx-accordion').click(function(){
			$(this).toggleClass("active");
			$(this).next('ul').slideToggle(600);
		});
	});

● 複数ブロック要素等にJSでタイトル要素に「xxxxx-accordion」クラスを書き込む場合

構造によっては走査は違いますが、一例として下記の様に3ブロックにアコーディオン処理のクラスを設定出来ます。この辺は工夫次第になります。(ID名などはCMSにより固有につけられています)


$('#x-block1,#x-block2,#x-block3').find('h3').addClass('xxxxx-accordion');
$('.xxxxx-accordion').next('ul').hide();

● アコーディオン開閉前後に、別のJS処理をしたい場合は、下記の様にすれば細やかな付随処理が出来る。
(処理状態が明示的で、スライドの前後に何らかの処理が可能です、クラス名は何でも良い)


	$(function(){
		$('.xxxxx-accordion').next().hide();
		$('.xxxxx-accordion').click(function(){

			$(this).toggleClass("active");

			if($(this).hasClass('active')){

				$(this).next('ul').slideToggle(600);
				//他の処理

			} else {

				$(this).next('ul').slideToggle(600);
				//他の処理
			}

		});
	});

● オブジェクトを保存して使用すると、エレメントの認識が早くなるため若干動作が速くなる。
(クラスでは余り違いが判らないが、IDの場合は結構早くなる、保存変数は任意)


		var accordItem=$('.xxxxx-accordion');
		accordItem.next('ul').hide();
		accordItem.click(function(){
			//処理
		});

もう少し掘り下げた、「同時開閉」などを後日「次のページ」で考えて見ます。


CSS

サンプル表示のためのCSS記載の一例です。通常はページのCSSに準拠しますので、余り記述することは無いと思います。つまり、ページのデザイン構成のままで「サイドバー」等をアコーディオン化出来ます。
新規のアコーディオンを挿入する際は、そのページの影響を受けますので修正します。


#x-block {
display:block;
width:200px;
height:auto;
margin:0;
padding:1px 0;
text-align:left;
border-bottom:1px #888888 solid;
background-color:#FFFFFF;
}
#x-block h3 {
width:188px;
height:20px;
margin:1px 0 0 1px;
padding:2px 0 0 10px;
line-height:20px;
color:#FFFFFF;
font-size:12px;
background-color:#BBBBBB;
cursor:pointer;
}
#x-block ul {
list-style:none;
width:auto;
height:auto;
margin:0;
padding:0;
background-color:#FFFFFF;
}
#x-block ul li {
list-style:none;
width:190px;
height:16px;
margin-left:5px;
padding:0;
border-bottom:1px #EEEEEE solid;
line-height:16px;
font-size:12px;
color:#555555;
background-color:#FFFFFF;
}




その他の、toggleクリック関数を使用しないアコーディオン

その他の、toggleクリック関数を使用しないアコーディオンのサンプルは、下記「デモ」ページに掲載しています。

【デモ】jQuery色々なアコーディオン


画像

サンプル画像 / 原則 使用者が用途に応じてご用意ください。

透過矢印画像 arrow.gif 21x44 透過矢印画像 arrow_2.gif 20x44 透過矢印画像 arrow_7.gif 19x40 透過矢印画像 arrow_5.gif 19x40 透過矢印画像 arrow_12.gif 19x40 透過矢印画像 arrow_13.gif 19x40

以上です。

 


[ この記事のURL ]


タグ:Accordion , jquery

 

ブログ記事一覧

年別アーカイブ一覧



[1]