【クライアントのわがままに応える! 】
アコーディオンを横向きに開閉したい!
今回作成したアコーディオンパネルは、上下にパネルが開閉する縦向き。では、パネルが左右に展開する「横向き」を注文された場合はどうしたらよいでしょうか。縦向きに比べると少し難易度は上がりますが、もちろんjQueryで作成できます。
まずHTMLを用意します。横向きのアコーディオンは、多くの場合、ラベル部分のテキストを横向きに回転させて表示しますが、HTMLとCSSでは横向きのテキストは表現できませんので、画像化する必要があります。ラベルを画像化するため、dl要素を包んでいるdiv要素、dt要素にそれぞれid属性を、dt要素内にはspan要素を追加します。
▼サンプル03(HTML部分)
<div>
<dl>
<dt id="step1"><span>Step.1</span></dt>
<dd><p>Lorem ...(中略)... venenatis.</p></dd>
<dt id="step2"><span>Step.2</span></dt>
<dd><p>Integer ...(中略)... accumsan. </p></dd>
<dt id="step3"><span>Step.3</span></dt>
<dd><p>Integer ...(中略)... imperdiet. </p></dd>
</dl>
</div>
CSSは以下のように設定します。
▼サンプル03(CSS部分)
div{
width:800px;
height:300px;
margin:50px auto;
overflow:hidden;
}
dl{
width:900px;
height:300px;
}
dt{
width:35px;
height:300px;
float:left;
}
dt span{
display:block;
width:100%;
height:100%;
text-indent:-9999px;
}
dt span.over{
cursor:pointer;
}
dt span.selected{
cursor:default;
}
dt#step1 span{
background:url("images/background-1.jpg");
}
dt#step1 span.over{
background:url("images/background-1-over.jpg");
}
dt#step1 span.selected{
background:url("images/background-1-selected.jpg");
}
dt#step2 span{
background:url("images/background-2.jpg");
}
dt#step2 span.over{
background:url("images/background-2-over.jpg");
}
dt#step2 span.selected{
background:url("images/background-2-selected.jpg");
}
dt#step3 span{
background:url("images/background-3.jpg");
}
dt#step3 span.over{
background:url("images/background-3-over.jpg");
}
dt#step3 span.selected{
background:url("images/background-3-selected.jpg");
}
dd{
margin:0;
width:695px;
height:300px;
float:left;
background:#D4D0C8;
overflow:hidden;
}
dd p{
width:655px;
text-indent:1em;
padding:20px;
}
dt要素とdd要素は、float:leftで横並びに配置しています。dl要素の幅は、dt要素(35px×3)、dd要素(695px)の合計ですので、本来は800pxになりますが、パネルの開閉時にタイミングによっては800pxを超えてカラム落ちする場合があります。そこで、100px余分な900pxに設定してカラム落ちを防いでいます。その代わり、dl要素の余分な100pxは、dl要素を包むdiv要素にwidth:800px;とoverflow:hidden;を設定して隠しています。
dd要素にoverflow:hidden;、dd要素内のp要素にwidth:655px;を設定しているのは、パネルの開閉時にdd要素の幅(width)が変更されても、パネルの中のテキスト領域が変化しないようにするためです。これらを設定しないと、スライドアニメーション中にテキストの表示が乱れます。
スクリプト部分は次のようになります。
$(function(){
$("dd:not(:first)").css({"width":"0px"})
$("dt:first span").addClass("selected");
$("dl dt").click(function(){
if($("+dd",this).css("width")=="0px"){
$("dt:has(.selected) +dd").animate({"width":"0px"})
$("+dd",this).animate({"width":"695px"})
$("dt span").removeClass("selected");
$("span",this).addClass("selected");
}
}).mouseover(function(){
$("span",this).addClass("over");
}).mouseout(function(){
$("span",this).removeClass("over");
})
})
初期状態の設定では、1番目以外のパネル(dd要素)のwidthを0pxに変更します。
$("dd:not(:first)").css({"width":"0px"})
1番目のdt要素に対してclass属性「selected」を追加し、1番目のdt要素dd要素を選択状態のスタイルに設定します。
$("dt:first span").addClass("selected");
if文で、クリックされたラベルのパネル(dd要素)の横幅が0の場合の処理を記述します。
if($("+dd",this).css("width")=="0px"){
ラベルがクリックされたら、class属性に「selected」が設定された要素を含むdt要素(選択状態にあるdt要素)の次に登場するdd要素の幅(width)を0に変更します。幅の変更には、任意のCSSプロパティの値をアニメーション付きで変化させる animate()を使います。
$("dt:has(.selected) +dd").animate({"width":"0px"})
同様に、クリックされた要素の次に登場するdd要素の幅(width)をanimate()で695pxに変更します。
$("+dd",this).animate({"width":"695px"})
クリックされたラベルを選択状態にするため、すべてのspan要素からclass属性「selected」を取り除き、クリックされたdt要素内のspan要素にclass属性「selected」を再設定します。
$("dt span").removeClass("selected");
$("span",this).addClass("selected");
最後に、mouseoverイベント/mouseoutイベントでロールオーバーの処理を設定したら完成です。
$("dl dt").click(function(){
(中略
}).mouseover(function(){
$("span",this).addClass("over");
}).mouseout(function(){
$("span",this).removeClass("over");
})
▼サンプル03(実行結果)
著者:西畑一馬(にしはた かずま)
to-R代表、Webクリエイター。PHPによるシステム開発や、CMSを利用したWebサイト制作、SEO対策などのマーケティング、コンサルティング、Webクリエイター向けの講座などを業務で行なっている。また、ブログto-RではJavaScriptやSEO対策、CSS、Movable TypeなどのWeb制作にかかわるさまざまな情報を発信している。
主な著書に「現場のプロから学ぶXHTML+CSS」(共著、毎日コミュニケーションズ刊)がある。
ソーシャルリアクション
この連載の記事
一覧へWebPro
jQueryとAjaxで作るスムーズページング
WebデザイナーのためのjQuery入門。jQueryのAjax機能を使ってスムーズなページングを実現する方法をチュートリアルで解説する。