Header Menu

JavaScript でタブ切り替え UI を実装する

先日、タブ切り換えタイプの UI を、JavaScript と CSS で簡単に実装する仕組みを探していて (他力本願)、ちょうど求めていたスクリプトが Archiva さんで紹介されていたので使わせていただきました。

時間がなかったので、できれば自分では書きたくないなぁ、なんかいいの公開している人いないかな~なんて思っていたのですが、おかげ様で助かりました。ということで、お礼を兼ねて紹介させていただきます。

タブ切替をサクッと実装 : Archiva

タブ切り換えを実装する JavaScript ライブラリやサンプルソースはいくつか存在しますが、私が求めていたのは JavaScript が OFF の時でもページ内リンクとしてタブが機能するもの。 Archiva さんのスクリプトはピッタリでした。

多少カスタマイズして使わせていただきましたが、まずは実際にどんな感じになるのかをこちらでご確認ください。

JavaScript ON ではタブ切り換えに、JavaScript を OFF にするとすべての内容が縦に表示され、タブがページ内リンクとして機能するようになります。

上のサンプルで使用している XHTML ソースは下記のとおり。 (一部省略)

<div id="javascript_tab_sample">
 
 <ul id="tab">
  <li class="selected"><a href="#w3c">W3C</a></li>
  <li><a href="#xhtml">XHTML</a></li>
  <li><a href="#css">CSS</a></li>
 </ul>
 
 <dl id="w3c">
  <dt>World Wide Web Consortium</dt>
  <dd>
   <p>...</p>
  </dd>
 </dl>
 
 <dl id="xhtml">
  <dt>XHTML</dt>
  <dd>
   <p>...</p>
  </dd>
 </dl>
 
 <dl id="css">
  <dt>Cascading Style Sheets</dt>
  <dd>
   <p>...</p>
  </dd>
 </dl>
 
</div>

タブで切り替わる部分 (サンプルでは dl 要素) にそれぞれ適当な id 属性値を付け、タブはリストでマークアップして各リンクを設定、ul 要素には id 属性も付加。デフォルトで選択状態になる左端のタブ (li 要素) に class 属性を付けておきます。サンプルでは 「selected」 という class 属性値を使用していますが、オリジナルでは 「present」 になっています。ここは変更がきくのでお好きなように。

次に JavaScript の用意を。オリジナルではスクリプトを 2つに分けているのですが、今回は 1つにまとめてみます。


/*--setup--*/
window.onload=function() {
tab.setup = {
   tabs: document.getElementById('tab').getElementsByTagName('li'),
   pages: [
      document.getElementById('w3c'),
      document.getElementById('xhtml'),
      document.getElementById('css')
   ]
}
tab.init();
}
/*--setup end--*/
  
var tab = {
   init: function(){
      var tabs = this.setup.tabs;
      var pages = this.setup.pages;
  
      for(i=0; i<pages.length; i++) {
         if(i !== 0) pages[i].style.display = 'none';
         tabs[i].onclick = function(){ tab.showpage(this); return false; };
      }
   },
  
   showpage: function(obj){
      var tabs = this.setup.tabs;
      var pages = this.setup.pages;
      var num;
  
      for(num=0; num<tabs.length; num++) {
         if(tabs[num] === obj) break;
      }
  
      for(var i=0; i<pages.length; i++) {
         if(i == num) {
            pages[num].style.display = 'block';
            tabs[num].className = 'selected';
         }
         else{
            pages[i].style.display = 'none';
            tabs[i].className = null;
         }
      }
   }
}

やっていることはなんとなくわかるかと。タブが増えたら、セットアップ部分を書き足せば OK です。セットアップ部分の 「window.onload=function() {...}」 は、JavaScript を 1つにまとめるために、追加しています。スクリプトの構造上、セットアップ部分を一番最後に実行しないといけないので。

でこのスクリプトを適当な名前 (サンプルでは tab_change.js) で保存して、先ほどの XHTML に読み込んであげます。場所は head 要素内とかで下記のように。

<script type="text/javascript" src="js/tab_change.js"></script>

これで出来上がり。とっても簡単です。

あとは、スタイルを当てて、さらにひと工夫するなら scriptaculous あたりでタブ切り替え時にエフェクトを加えてみるとかすると面白いかも。 Apple iLife ' 08 のページなんかは参考になるかと思います。

今回使用した、サンプルページのソース一式を下記に置いておきますのでどうぞ。

tab_sample.zip (3.4KB)

あと、同じようなタブ切り替え用の JavaScript ライブラリとしては、Control.Tabs なんかもいいかもしれません。

Add to Bookmarks
  • Hatenaブックマークに追加
  • del.icio.usに追加
  • POOKMARK Airlinesへ追加
  • livedoorクリップへ追加
  • ニフティクリップへ追加
  • Buzzurlにブックマーク
  • newsingへ投稿
  • Choixへ追加
  • Furlへ追加
  • Blinklistへ追加
  • Redditへ追加
Advertisement

comment & trackback

TRACKBACK URL : http://hyper-text.org/cms/mt-tb.cgi/398

trackback to this entry

... 0 trackback

comments

初心者太郎, October 30, 2007 - 11:16.

はじめまして。
このサイトを拝見いたしまして、早速勉強してました。
そこで質問がございます。

firefoxでは普通に動くのですが、IEですと、ページ内リンクとなってしまいます。

さらにエラー表示、オブジェクトがありません。
と出ています。

> > pages[i].style.display = 'none';

ラインは上記を示しています。

何かお分かりかヒントがございましたらご教授願えませんでしょうか?
よろしくお願いいたします。

WWW WATCH, October 31, 2007 - 08:56.

> 初心者太郎さんコメントありがとうございます。

実際のページを見ていないのでなんともいえませんが、エラーを見る限り、id属性値の付け忘れ、記述ミスではないでしょうか?同じid属性値がページ内に複数あるとか。

初心者太郎, October 31, 2007 - 11:23.

アドバイスありがとうございます。

idは間違いなかったのですが、

<div id="page1" name="page1">

としましたら、 IEでのエラー表示はなくなりました。

ただそれだけのことに丸一日費やしてしまった初心者です。

WWW WATCHさん、ありがとうございました。また、すばらしいブログに出会えて光栄です。

今後とも参考とさせていただきます。よろしくお願いいたします。

けいこん, January 24, 2008 - 00:03.

はじめまして。

こちらのタブ切り替えメニューが素晴らしいので使わせていただきたいのですが、ひとつ質問です。

1ページに2ヶ所、このタブ切り替えメニューを設置したくて、jsファイルを【tab_change1.js】【tab_change2.js】という風に2つ用意して、

/*--setup--*/
window.onload=function() {
tab2.setup = {
tabs: document.getElementById('tab2').getElementsByTagName('li'),
pages: [

という風に書き直し、HTMLの方のidを下記のように2種類に分けたのですが、

<div id="javascript_tab_sample2">
<ul id="tab2">
<li class="selected"><a href="#w3c">W3C</a></li>
<li><a href="#xhtml">XHTML</a></li>
<li><a href="#css">CSS</a></li>
</ul>

ひとつめのタブメニューはちゃんと動作してるのですが、ふたつめのタブメニューは全部が表示されています。

JavaScriptの初心者で、やろうとしていることが間違っているのか、書き換えたところが違うのか、・・・さっぱり困っています。

もし、お時間ありましたら、何かヒントや解決策をご教授をお願いしたいと思います。

宜しくお願い致します。

WWW WATCH, February 6, 2008 - 01:20.

けいこんさんコメントありがとうございます。ご返答遅くなりました。

簡単に言えば、window.onloadの仕様です。ページ内で複数のwindow.onloadを記述しても正常に動作しません。

addEventListener()の使用や、prototype.jsを導入してEvent.observe()で代替えするなどの対策が必要です。

詳しいことは検索してみてください。

jax, February 25, 2008 - 18:21.

はじめまして、タブの切り替えで質問があります。
最初の状態を2つ目のタブと2つ目の内容にしておきたい時になやんでおります。
タブにはclass=selectedとすればいいと思うのですが2つ目の内容を表示出来ませんでした。

loadされた時に、prototype.jsのEvent.observe()なりで
カレント状態にしたいタブの内容を教えた上げればいいのかな?と思ったので

<script>Event.observe(window, 'load', function(){tab.showpage(this)})</script>

現状こんな感じになるんじゃないかと目をつけました
thisの部分に直接どの命令を下せばいいのかが分からず苦心しております。

もしよろしかったら、ヒントなど教えていただけると助かります。
よろしくお願いします。

WWW WATCH, February 25, 2008 - 21:19.

jax さんコメントありがとうございます。

2つ目の内容をデフォルト表示ですが、簡単にやるなら、tab_change.js 内の 31行目あたり、

if(i !== 0) pages[i].style.display = 'none';

という部分を、

if(i !== 1) pages[i].style.display = 'none';

に変えればそうなると思いますよ。

jax, February 26, 2008 - 05:26.

コメントの素早いご返答、大変助かりました。

ありがとうございました。

mos, March 21, 2008 - 23:59.

はじめまして、タブ切り替えを探していてこのサイトにたどり着きました。自分の探していたものとまさに同じで、大変参考にさせていただき、自分のサイトでも使用しようと考えています。

早速データをダウンロードし、いろいろ手を加えているのですが、根本的なところでわからないところがあり、教えていただきたく。。

リストを3つから2つに変更しようとしているんですが、以下の修正の行いましたが上手くいきません。サンプルでいう所の修正箇所は

・tab_sample.shtmlファイルの<li><a href="#css">CSS</a></li>を削除
・tab_sample.shtmlファイルの<dl id="css">~</dl>までを削除
・tab_change.jsファイルのdocument.getElementById('css')を削除

になります。これだけでは足りないでしょうか。。

上記の修正を行うと、2つ目のタブがIE7でタブのテキスト部分をクリックするとアンカーリンクになってしまいます。テキスト部分でない箇所をクリックすると正常に切り替えが行われます。Firefoxでは正常に切り替えができるようです。

大変お手数ですが、お教えいただけないでしょうか。よろしくお願いします。

WWW WATCH, March 23, 2008 - 01:36.

mos さんコメントありがとうございます。

実際のソースを見ていないので何とも言えませんが、もしかすると

document.getElementById('css')

を削除する際にその上の行、

document.getElementById('xhtml'),

の最後の「,」を削除し忘れていませんか?

mos, March 23, 2008 - 02:32.

素早いご返答での確認ありがとうございます。

アドバイスを試してみたところ、問題なく表示することができました。
「,」をすっかり見落としていました。。お恥ずかしい限りです。。

今後ともこのサイトの情報を参考にさせていただきます。
ありがとうございました!

pacpac, April 25, 2008 - 09:39.

はじめまして、Archivaさんの所で質問させていただいたのですが返事がない様なので、申し訳ありませんがコメントさせて頂きました。
タブの事で質問なんですが、タブで開いたページのタブをもう一度クリックすると、別ページにジャンプするような事は可能でしょうか?
JavaScript初心者で、色々と調べてみたのですがどうして良いのかさっぱりでした・・・。
よろしければヒントでも頂けないでしょうか。
よろしくお願いします。

nana, June 5, 2008 - 16:48.

はじめまして、自分でもいろいろやってみたのですが、どうしてもわからないので質問させていただきます。
javascriptでリスト部分を期間に class="selected"を切り替えるようにはしたのですが、リストの選択はかわるのですが、内容(dt)がいつも同じものが表示されてしまいます。
先の質問にあったように
if(i !== 0) pages[i].style.display = 'none';
で指定したところが毎回でてしまうので可変にする事はできないでしょうか?

kome, June 24, 2008 - 18:03.

はじめまして。
すばらしいので、使わせていただいてます。
どうしてもわからず質問させてください。
1つのページこのタブデザインのエリアを2つ作りたいのですが、名前を変えたjsをもうひとつ用意して2つ読み込ませると、最初に読み込むjsが効かなくなります。
jsファイルのどの部分を変えれば1ページに2つつかえるようになるのでしょう??知識不足でもうしわけないです・・

post your comment

comment form

* All Fields Required.

RSS Feed
  • Add to Google Reader
  • Add to My Yahoo
  • Add to netvibes
  • Subscribe in NewsGator Online
  • Subscribe in livedoor Reader
  • Subscribe in Hatena RSS Reader
  • Subscribe in Bloglines
  • Feed Count by FeedBurner