Note: この記事は、3年以上前に書かれています。Webの進化は速い!情報の正確性は自己責任で判断してください。
他ページからそれぞれのタブにリンクすることってできますか?
—タブ切替をサクッと実装, くりはらさんのコメント
確かに便利そうなので、やってみました。ページ内リンクと同じように「なんたら.html#Contents」とかってURLでアクセスできます。意外と簡単~。サンプルは以下の画像から。
考え方
tab.dive = function(){
var hash = window.location.hash;
hash = hash.split("?");
hash = hash[0].split("#");
if(hash[1] == 'page2') tab.showpage(tab.setup.tabs[1]);
if(hash[1] == 'page3') tab.showpage(tab.setup.tabs[2]);
if(hash[1] == 'page4') tab.showpage(tab.setup.tabs[3]);
if(hash[1] == 'page5') tab.showpage(tab.setup.tabs[4]);
}
URLの「#」以下の部分は「location.hash」で取得できます(2行目)。#以下はID名。
そこからロード時に対応するページを開くよう「tab.showpage()」と関連付けてやれば良い(6行目以降)。
追加部分
上記のままでも動作しますが、いちおパッケージ化してみましょうか。下記のコードを「tab」オブジェクトに追加します。
dive: function(){
var hash = window.location.hash;
hash = hash.split("?");
hash = hash[0].split("#");
var tabs = this.setup.tabs;
var pages = this.setup.pages;
for(i=0; i<pages.length; i++) {
if(pages[i] == document.getElementById(hash[1])) this.showpage(tabs[i]);
}
}
で、「tab.init()」でセットアップしてから「tab.dive()」を呼び出してやれば良い。tab.dive()はURLからID名を抜き出し、そこから取得したオブジェクトと先に設定したページオブジェクトを比較して、一致すればそのページを開く。
面倒ならtab.init()の最後でtab.dive()を呼び出すようにしても良いね。以下のようになる。
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; };
}
this.dive();
},
... goodness ...
こうすれば起動部分のスクリプトは前回とまったく同じなので、本体を入れ替えるだけで済む。どないでしょ?
memo: ちなみに前回の記事で起動部分を<body>内に置くように勧めたのは、onloadで起動するとロード時に一瞬だけタブが展開されて見えるから。onloadイベントが読み込み完了時に実行されるモノだからですね。
Note: スパム対策が面倒なので、コメント投稿を廃止しました。以前のコメントは残します。
ご意見・ご要望はtwitter@sigwygかはてブコメントにて。
26 Comments
コメントの改行が吹っ飛んじゃいました。ごめんなさいっ!
それはともかくt_dragon_200さん、こんにちわ。
たとえば...
<div id="page4">
<iframe src="http://archiva.jp/" width="100%"></iframe>
</div>
...とか、単純に <iframe id="page4"> とかでも問題なくできました。
もちょっと情報Plz! 2007–11–26 15:14
この「他ページから直接タブにアクセスする」を利用させて頂いているのですが、どうしてもうまくできない点があるので、
教えて頂ければ幸いです。
/=============================================================================
・分からない点
①同ページ内でのリンクジャンプがうまくいかない
(例:http://sample.com/index.html#page1内にある#page2へのリンクにうまく飛べない)
②#page2にあるname属性に直接ジャンプしたい
(例:http://sample.com/index.html#page2にある#sampleなどのリンクへジャンプできるようにしたい)
==============================================================================/
上記の事象が改善できず、試行錯誤しております。
お忙しいとは思いますが、ご返答頂ければ幸いです。 2008–09–23 13:13
ようやく仕事が落ち着いたので回答をば!
タブ内にページ内リンク移動したいとのこと。ちょいと整理しましょうか。
1.タブ切替JSを使っていてもページ内移動はできる。
2.表示部分の「#deeplink」などへの移動はできる。
3.非表示タブ内への移動は「飛び先が存在しない」 ←display:noneしているため
Y2Tさんの「分からない点1」が
「http://sample.com/index.html#page1」内で
「#page2」へのリンクを押したときに「タブが展開しない」という意味であれば、
これは tab.div() の実行がページ読み込み時だからです。
ページ内リンクでは再読み込みしないので、手動で開いてやる必要がありますね。
Y2Tさんの「分からない点2」が
「展開したタブの中の指定ポイントに移動したい」という意味であれば、
タブを展開した上で、指定位置までスクロールする必要がありますね。
幾つか方法は考えられますが... 言ってることは合ってるかな? 2008–10–02 04:46
お急がしいなかご回答頂き本当にありがとうございます。
大変参考になる意見でしたので、その意見を踏まえてもう一度作成し、いじってみます!
力不足な私に貴重なアドバイスをありがとうございました。
archiva様にて紹介される記事は大変参考になるものが多いので興味深く読ませて頂いております。
今後もサイト運営がんばって下さい! 2008–10–02 22:08
いつも見させていただいてます。
中でもこのタブ切り替えは大変参考になりました。ありがとうございます。
そこで質問なのですが、
タブの中にタブをつくる・・・ことは可能なのでしょうか。
javascript初心者なので、いろいろ試行錯誤しているのですが
どうしてもできません。
状況としては、javascriptがoffになっている様な形(タブをクリックしてもページ下へジャンプするだけ)です。
ソースはarchivaさんのソースをほぼそのまま使用させていただいておりますm(_ _)m
もしできるのであれば、ヒント等教えていただけると大変助かります。
よろしくお願いします。。 2008–11–19 21:23
タブ内のタブですか。結論から言うと、できます。
考慮すべき点は2つ。
1.tab.setup.tabs および tab.setup.pages の登録
2.クリック時に全てのタブを消してしまう → タブ内タブでのクリックで親タブも消える
まず1の登録ですが、基本的にリスト形式で渡せば認識してくれます。
ただしgetElementsByTagName()が返すのは配列「ではなく」、「配列のようなオブジェクト」なので、
複数のタブを登録したい場合には結合するのが難しくなります。
var tabs1 = document.getElementById('tab1').getElementsByTagName('li');
var tabs2 = document.getElementById('tab2').getElementsByTagName('li');
tab.setup.tabs = tabs1.concat(tabs2);
...ではエラーになると言うこと。
スマートな方法は思いつきませんでしたが、ちょっと泥臭く
tab.setup.tabs = [
tabs1[0],
tabs1[1],
tabs1[2],
tabs1[3],
tabs1[4],
tabs2[0],
tabs2[1],
tabs2[2],
tabs2[3],
tabs2[4]
];
...とでもすればできます。
あとは2の切替ですが、これはtab.showpage()内のIF分岐でどうにかできます。
少なくとも俺はできました。頑張ってください^^b 2008–11–23 23:11
タブ内タブについてご質問させて頂いたものです。。
ご多忙中かと存じますが、早速のご返答ありがとうございました。
あれからいろいろやってみたのですが・・・すみません。どうしてもできなくて(^-^;)
ご指摘頂いた点の2番はなんとなく理解できたのですが、1番のイメージがわからなくて。。。
>var tabs1 = document.getElementById('tab1').getElementsByTagName('li');
>var tabs2 = document.getElementById('tab2').getElementsByTagName('li');
>tab.setup.tabs = tabs1.concat(tabs2);
この部分に関しましては、なんとなくわかりました。外タブと内タブをそれぞれ宣言し、配列として結合しているってことですよね。。?
(間違ってたら恥ずかしいです(^^;)..)
ただし、それではだめで、
// ※page1~5が外タブ、page6,7,8が内タブ(page1内)の場合※
tab.setup = {
tabs = [ tabs1[0], tabs1[1], tabs1[2], tabs1[3], tabs1[4], tabs2[0], tabs2[1], tabs2[2] ]
pages:[ document.getElementById('page1'),
・
・
document.getElementById('page8')
]
}
tab.init();
と、このようにするということなのでしょうか。。??
お時間があるときでかまわないです。いつかご返答いただければ幸いです。
どうかよろしくお願いします。 2008–11–27 16:44
配列として結合しようとしているのだけど、getElementsByTagName()が返すのは配列ではないのでconcat()は使用できない、というのが正確かな。これができればスマートなんですけどねー。
...で、toshiさんが出している方法で動かないのは、単純に文法エラーですね。基本的には合っていますよ。「オブジェクトリテラル」でググってみてください。 2008–12–01 06:16
なるほど。「オブジェクトリテラル」という名の書式なんですね。
ググってみて、何箇所か修正をしたら・・・できました。
今回のことでまた一つ勉強になりました。
本当にどうもありがとうございました。m(_ _)mペコリ 2008–12–01 12:04
色々お勉強させていただいております。
1つご質問なんですが、
タブを別のタブに切り替え、リロードすると最初のタブに戻ってしまいます。
リロードしても、リロード前のタブ情報を保持するにはどうすればよろしいでしょうか?
タブページの中の本文中にテキストリンクがあるのですが、そのリンク先に飛んでから再び元のタブページへ戻るとタブの一番初めに設定されているページに戻ってしまってうので使い勝手が悪くなってます。
firefoxではリロードしてもリロード前のタブのページのままなのですが、IEだと最初に設定したタブのページに戻ってしまいます。
もしよろしければ解決方法をご教授願います! 2009–02–06 12:15
リロードで初期化されるのは当たり前ですよね。
戻るボタンでタブページに戻って来たときに、初期化されない方法を教えていただきたいのです。
よろしくお願い致します。 2009–02–06 12:45
そですねー履歴の表示方法はブラウザやCMSによって違うのでなんとも言えないのですが、展開情報をCookieに保存しておけば可能かもしれません。
Cookieのget/setは以下の記事が参考になるかも。できたら教えてくださいねー^^b
http://archiva.jp/web/javascript/cookie-memo.html
http://archiva.jp/web/javascript/save_preset.html 2009–02–06 23:48
以上、よろしくお願いします。 2009–03–27 01:15
意図したとおりに動いたなら、とりあえず問題ないでしょう。
コードの改変・利用は自由です。どうぞ使い倒してやってください。
ま、コメントにでもURL書いて貰えたら嬉しいですけどね! 2009–03–28 04:00
わかりづらい文章で申し訳ありません。よろしくお願いします。 2009–07–06 20:29
あーなるほど。
これはですね、スクリプトとしてはURLから「#」以後の文字列を取得してるだけで
スクロール自体はスクリプト起動前に「ページリンクとして」既にされているのです。
なので方法としては、
1. 「location.hash」でなく「location.search」で取得する
2. タブ展開後に別の関数を起動して任意の位置まで再びスクロールする
...の、いずれかになると思います。
前者の場合には「tab.dive」の2〜3行目を
var hash = window.location.search;
hash = hash.split("=");
...のようにした上で、「./tab-menu2.html?page=page5」のような呼び出し方になると思います。
後者の場合は「tab.dive」の最後にscroll()メソッドでも追加して任意の位置まで。
以下の記事が参考になるかと
http://archiva.jp/web/javascript/smooth_scroll.html 2009–07–06 22:51
巧くいかなかったとしたら他の部分だと思いますよー
Firebugのログをまめに見とくと良いでしょう。 2009–07–07 15:20
hash = hash[0].split("#");を残したままでいました。
2番の方法でやったみましたら、一瞬設定位置にスクロールしますがまた元に戻ってしまいました。たぶんスクロールさせるタイミングが
悪いのだと思います。これからも時々のぞかせていただき勉強していきたいと思います。よろしくお願いします。 2009–07–08 00:48
他の人が質問されているようなのですが答えが
///////////////////////////////////////////////////////////////////////////
「http://sample.com/index.html#page1」内で
「#page2」へのリンクを押したときに「タブが展開しない」という意味であれば、
これは tab.div() の実行がページ読み込み時だからです。
ページ内リンクでは再読み込みしないので、手動で開いてやる必要がありますね。
///////////////////////////////////////////////////////////////////////////
どうやって内部リンクを再読み込みさせればよいのでしょうか? 2009–07–24 09:10
tab.init() はページ読み込み時に一回実行されているだけなので、
タブ内のリンクのクリックではJavascriptが実行されません。
「手動で開いてやる」てのは任意のリンクにonclickイベントを追加してやるとかで
「tab.dive() を動かしてやってください」という意味です。
これ以上は言いませんよ?
せめて理解する努力はしてください... 2009–07–28 02:31
ほんとに何もわからないのでヒントを頼りにいろいろやってみます。 2009–08–03 00:02
きりがないので、コメント欄にてJavaScript初級講座をするつもりはありません。
もうちょい具体的な質問なら答えようがあります。
頑張ってください。 2009–08–03 13:52