再・改良版:タブで表示切り替え jQuery プラグインなし
CSS3 ・ サンプルあり ・ メニュータブみたいなメニューで、クリックすると同じページ内(同じHTMLファイル内)で表示を切り替える方法。
jQueryで、プラグインを使わずにできる方法、ソースを紹介します。
head内にjQueryを読み込む記述
以下をheadに記述します。
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
HTMLのソース
<div class="full_content">
<div class="menu active">ホーム</div>
<div class="content">
ここに内容が入ります。
</div>
<div class="menu">画像</div>
<div class="content">
ここに内容が入ります。
</div>
<div class="menu">リンク</div>
<div class="content">
ここに内容が入ります。
</div>
<div class="menu">入力</div>
<div class="content">
ここに内容が入ります。
</div>
<div class="menu">テーブル</div>
<div class="content">
ここに内容が入ります。
</div>
</div>
サンプルから一部内容を省略していますが、「ここに内容が入ります。」の部分は、切り替わったときにそれぞれ表示される部分です。
ハイライトした2行目は後述します。
CSSのソース
.full_content {
width:508px;
height:380px;
position:relative;
margin:10px auto;
clear:both;
}
.menu{
width:100px;
height:25px;
background:#9C9;
float:left;
list-style:none;
padding:10px 0 0;
margin-left:2px;
text-align:center;
display:block;
cursor: pointer;
color:#FFF;
}
.menu:first-child {
margin-left:0;
}
.active, .hover {
background:#6CC;
font-weight:bold;
}
.content {
width:478px;
height:320px;
border:#6CC 5px solid;
background:#FFF;
top:32px;
left:0;
padding:10px;
position:absolute;
}
では上記のソースでハイライトしたポイントをざっくりと説明します。
- 4行目と36行目
- 18行目
- 21行目
4行目のposition:relative;に対し40行目にposition:absolute;を記述しています。
ここでは.full_contentが親要素で.contentが子要素になります。
cursorというプロパティでマウスカーソルの形を変更できます。
ここではリンクを使っていませんのでマウスを乗せても通常の矢印マークとなってしまい、クリックできるのが一見わかりません。
クリックすると切り替わる仕様ですので、マウスオーバー時に指マークになるように変更。
:first-childというのは一番目の子要素に適用できるセレクタです。今回の場合は、.menuの一番目、つまりタブの一番左側だけmargin-left:0;にという意味ですね。
15行目でmargin-left:2px;と記述していますが、CSSは後から記述された方が優先されるので21行目の方が適用されます。
jQueryのソース
head内に記述するときは上記で記述したjquery本体よりも後に記述するのを忘れずに!
<script type="text/javascript">
$ (function(){
$ (".content:not('.active + .content')").hide();
$(".menu").hover(function(){
$ (this).addClass("hover")
},
function(){
$(this).removeClass("hover")
});
$ (".menu").click(function(){
$(".menu").removeClass("active");
$ (this).addClass("active");
$(".content:not('.active + .content')").fadeOut();
$ (".active + .content").fadeIn();
});
});
</script>
jQuery説明
- 3行目
CSSで記述した.contentを.hide()、つまり隠したい状況です。.contentを隠したいだけなら、2行目は
$ (".content").hide();
となります。
HTMLのソースでハイライトした2行目を見てみると、divにactiveというクラスが付いています。
ページが読み込まれた時には、この部分は隠さないようにします。
今回はページが読み込まれた時に.active + .contentの部分は隠さないようにするので、:not(‘.active + .content’)を追加。
:not()は()以外となります。
ここでは.activeの直後の.content以外の.contentを隠すとなります。
div.menuにhover(マウスオーバー)したときに、CSSで記述したhoverというクラスを追加し、マウスが外れたときにhoverというクラスを外す、ということです。
.menuをクリックしたときに
- div.menuからactiveというクラスを消す。
- クリックしたdiv.menu(ここではthis)にactiveというクラスを追加。
- .active + .contentでない.contentを.fadeOut()、つまりフェードアウト(ゆっくりと消す)する。
- activeというクラスがついたdiv.menuの.contentを.fadeIn()、つまりフェードイン(ゆっくりと出てくるようにする)する。
ということが起こるようになっています。
jQueryは使いこなせるようになるとデザインの幅が広がって良いと思います。
ちなみに私は「Web制作の現場で使う jQueryデザイン入門」という本で初めてjQueryを勉強するようになりました。
CSSとHTMLが分かる人にはお勧めの本です。自分でコードが書けるようになります。
2014.09.26 4:43 PM
こんにちは。はじめまして。
現在、職場でWEBサイトを作成しており、jqueryを使ったタブの切り替えを試行錯誤しています。
こちらのサイトでのサンプルがとても分かり易く参考にさせていただいています。
その中で一つお聞きしたいことがございます。
.menu .active .hover(通常時、選択時、マウスオーバー時)でそれぞれ違う色を設定したいときはどうすればよろしいでしょうか?
CSSの.activeを独立させて違う色を設定したのですが反映されませんでした。
その後スクリプトの方でも色々試してみたのですがダメでした。
素人意見で恐縮なのですがよろしければご教授下さい。
お手数をおかけいたしますがどうぞよろしくお願いいたします。
2014.09.26 7:45 PM
amさん
参考にしていただいて光栄です。
上記CSSの記述の一番最後に下記のソースを追加すると、マウスオーバー時の色が変わりますが、いかがでしょうか。
.hover { background:#afeeee; } .hover + .content { border:#afeeee 5px solid; }試してみてくださいね。
2014.09.29 3:54 PM
ご回答ありがとうございます。
無事にマウスオーバー時の色を変えることができました。ありがとうございます。
加えてもう1点お聞きしたいことがございます。
現在の状態だと.active(選択時)が適用されているところにもカーソルを乗せると.hoverが適用されてしまいます。
この部分をカーソルを乗せても変化が起きない(.activeが適用されたまま)ようにするにはどうすればよろしいでしょうか。
上記のjqueryのソースの一部に$(“div:not(.active)”);などを加えてみたのですができませんでした。
重ね重ねで申し訳ございませんが、ご教授いただければ幸いです。
どうぞよろしくお願いいたします。
2014.09.29 6:57 PM
amさん
選択時に変化をさせたくないのであれば、さきほど加えたCSSを消していただき、上記の記事内のCSSに再び戻りましょう。
それで24行目から27行目を下記に書き換えて見てください。
.hover { background:#afeeee; font-weight:bold; } .active { background:#6CC; font-weight:bold; }2014.01.19 11:47 PM
素敵なスクリプトですね。
いま、カスタマイズの試行錯誤をしています。
contentクラスのCSSについて、position:absolute をなんとか外せないでしょうか?
というのは、これがなければ高さの指定を消すことができて、
widthを100%にすれば、レスポンシブになるからです。
素人意見で恐縮ですが、
例えばmenu要素を先に記述して、
コンテンツ要素にidでも振りながら後で記述して、
それをスクリプトでつなげる、というのはできないでしょうか?
コンテンツスライダーやタブスクリプトを探して数十時間、
色々なスクリプトを見てきましたが、
その中で1番シンプルで分かりやすいです。
あと1歩・・・お願いしたく存じます。
繰り返しになりますが、素敵なスクリプトをありがとうございます。
2014.01.21 12:40 PM
コメントありがとうございます。
ご質問の通り、CSSのabsoluteを取る方法について考えてみました。
できないことはないのですが、jQueryの読み込みの際に一瞬表示が遅れるためあまりスマートではない気がします。
一応ソースを紹介します。
HTMLソース
.menuと.contentに対応するようにそれぞれn1、n2のようにクラスをつけます。
n3~n5は省略しますが同様に。
<div class="full_content"> <div class="menu n1">ホーム</div> <div class="menu n2">画像</div> <div class="content n1"> ここに内容が入ります。 </div> <div class="content n2"> ここに内容が入ります。 </div> </div>CSSソース
上記の記事から変更したクラスのみ下に載せます。
.full_content { width:97%; height:auto; clear:both; margin:0 5px; } .menu{ width:auto; height:25px; background:#9C9; float:left; list-style:none; padding:10px 10px 0; margin-left:2px; text-align:center; display:block; cursor: pointer; color:#FFF; } .content { width:100%; height:auto; border:#6CC 5px solid; background:#FFF; float:left; padding:10px; }jQueryソース
n3~n5は省略します。
$ (function(){ $ (".content:not('.content.n1')").hide(); $(".menu").hover(function(){ $ (this).addClass("hover") }, function(){ $(this).removeClass("hover") }); $ (".menu.n1").click(function(){ $(".menu").removeClass("active"); $(".menu.n1").addClass("active"); $(".content:not('.content.n1')").fadeOut(); $ (".content.n1").fadeIn(); }); $ (".menu.n2").click(function(){ $(".menu").removeClass("active"); $(".menu.n2").addClass("active"); $(".content:not('.content.n2')").fadeOut(); $ (".content.n2").fadeIn(); }); });サンプルはこちらに作りました。
上記の記事のサンプルをもとに変更してみましたが、もっと別の良い方法が思いついたらまた書きたいと思います。