質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.37%

  • JavaScript

    21543questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jsだけでタブメニューをつくるコードに関する質問

解決済

回答 3

投稿

  • 評価
  • クリップ 1
  • VIEW 1,208

takane

score 47

どうやら投稿に失敗したようなので、
再度投稿いたします。
※二重投稿になっていたらすみません。

こんにちは。
私は今jsだけでタブメニューを作る勉強をしています。
動画サイトで習ったやりかたはdata-id(dataset)を使うやり方
なのですが、これではhtml5以外では使えなくなってしまうらしいと
聞きました。

そこで下記のURLを見て成り立ちを勉強しているのですが、
知識不足と経験不足で読み解くことができていません。

わからないところを列挙しますので、
どなたか親切な方、解説していただけないでしょうか・・・。
一応自分でわかるところまでは解析しています。

参考URL
http://gihyo.jp/dev/serial/01/crossbrowser-javascript/0021

質問1
var id = link.hash.slice(1);の部分
hashというのはlink(aタグ)の#がついている部分を抜き出せということですか?
また、sliceは取り出したidの配列の0番目から1番目までを取り出すという意味で
あっていますか?

質問2
function tab_init() の中の page.style.display = 'none';のぶぶん
このタイミングでpageクリアランスをかけてしまったら
なにもボタンをおさなくても最初からすべてのdivが表示されなく
なってしまいませんか?

<div class="js-tabs">
  <ul id="tab_menu1" class="tab_menu">
    <li><a href="#page1-1">Page 1</a></li>
    <li><a href="#page1-2">Page 2</a></li>
    <li><a href="#page1-3">Page 3</a></li>
  </ul>
  <div id="tab_content1" class="tab_content">
    <div id="page1-1" class="page">
      Page 1
    </div>
    <div id="page1-2" class="page">
      Page 2
    </div>
    <div id="page1-3" class="page">
      Page 3
    </div>
  </div>
</div>
.js-tabs ul.tab_menu{
  list-style-type:none;
  margin:0px;
  padding:0px;
}
.js-tabs ul.tab_menu li{
  display:inline;
  background:#666;
  margin:0px;
  padding:2px;
}
.js-tabs .tab_menu li a{
  padding:3px;
}
.js-tabs .tab_menu li a:link,
.js-tabs .tab_menu li a:visited{
  background-color:#666;
  color:#fff;
}
.js-tabs .tab_menu li a.active:link,
.js-tabs .tab_menu li a.active:visited{
  background-color:#444;
  color:#fff;
}
.js-tabs .tab_menu li a:hover{
  background-color:#333;
  color:#f0f;
}
.tab_content{
  position:relative;
  height:200px;
}
.tab_content div.page{
  width:450px;
  height:200px;
  position:absolute;
  color:#222;
}
#page1-1{
  background-color:#ffa;
}
#page1-2{
  background-color:#faf;
}
#page1-3{
  background-color:#aff;
}
(function(){
var menu = document.getElementById('tab_menu1');
var content = document.getElementById('tab_content1');
var menus = menu.getElementsByTagName('a');
var current; // 現在の状態を保持する変数
for (var i = 0, l = menus.length;i < l; i++){
  tab_init(menus[i], i);
}
function tab_init(link, index){
  var id = link.hash.slice(1);
  var page = document.getElementById(id);
  if (!current){ // 状態の初期化
    current = {page:page, menu:link};
    page.style.display = 'block';
    link.className = 'active';
  } else {
    page.style.display = 'none';
  }
  link.onclick = function(){
    current.page.style.display = 'none';
    current.menu.className = '';
    page.style.display = 'block';
    link.className = 'active';
    current.page = page;
    current.menu = link;
    return false;
  };
}
})();
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

checkベストアンサー

+3

質問1:

hashというのはlink(aタグ)の#がついている部分を抜き出せということですか?

おおよそその通りです。正確にはURL文字列の#を含めて#以降の文字列を取得します。

console.log(link.hash);
// #page1-1

sliceは取り出したidの配列の0番目から1番目までを取り出すという意味で
あっていますか?

いいえ、第1引数にstart位置、第2引数にend位置を指定しますが、
第2引数が省略された場合は、start位置からそれ以降の文字列を切りだします。

console.log(link.hash.slice(0));
// #page1-1

console.log(link.hash.slice(1));
// page1-1

console.log(link.hash.slice(2));
// age1-1

console.log(link.hash.slice(0,1));
// #

質問2:

なにもボタンをおさなくても最初からすべてのdivが表示されなくなってしまいませんか?

いいえ。
以下のようにしてみるとcurrentの初期値が分かります。

var current;
console.log(current);
//undefined

undefinedなので

if (!current){ // 状態の初期化


が成立するため、上記if文のelseには入らず、page.style.display = 'none'は実行されない、ということになります。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/10/05 14:39

    すみません。あと1ミリ理解が及ばないところがあるので教えていただけませんでしょうか・・・。

    いつも日本語に変換しながらプログラムを理解しているのですが、
    いわば下記のようなことでしょうか?

    var current;
    console.log(current);
    //undefined


    currentという箱を作ります。
    currentの中身を教えてください。
    //定義されていない状態です。

    if (!current){


    もし、currentの中身がfalse以外のものがはいっていたら


    今まではif以降を「currentの中身が定義されていない状態ではなかったら」と
    理解していたために微妙なズレがありました。

    キャンセル

  • 2017/10/05 14:58

    わ・・・わかった!!!
    たぶん大丈夫だと思います!!
    またわからないところがあったらよろしくお願いします!
    ありがとうございました!

    キャンセル

  • 2017/10/05 15:01

    日本語に変換しながら理解するのは良いことではありますが、正しく変換しないと意味不明になってしまうので注意です。
    プログラム言語は英単語と同じで1つの表現で様々な意味合いを持つことがよくあるからです。
    文脈から意味を読み取る力も必要ですね。

    というので、
    > if (!current){

    この部分は、false・undefined・nullなども同じように判定可能で、いずれも!current ===trueと判断されます。
    厳密なチェックをするのであれば、
    if ( typeof(current) === "undefined") となりますね。

    キャンセル

+3

hashというのはlink(aタグ)の#がついている部分を抜き出せということですか?

はい。

また、sliceは取り出したidの配列の0番目から1番目までを取り出すという意味で
あっていますか? 

いいえ。
↓以下のとおり、

取り出しを開始する、0 から始まるインデックス。
String.prototype.slice() - JavaScript | MDN

1番目以降を取り出します。 

なにもボタンをおさなくても最初からすべてのdivが表示されなくなってしまいませんか?

その前に

if (!current){ // 状態の初期化
    //...
  } else {


とあります。初期状態では、undefinedでしょうから条件が成立し、page.style.display = 'none';は実行されないと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/10/05 14:40

    すみません。あと1ミリ理解が及ばないところがあるので教えていただけませんでしょうか・・・。

    いつも日本語に変換しながらプログラムを理解しているのですが、
    いわば下記のようなことでしょうか?

    var current;
    console.log(current);
    //undefined


    currentという箱を作ります。
    currentの中身を教えてください。
    //定義されていない状態です。

    if (!current){


    もし、currentの中身がfalse以外のものがはいっていたら


    今まではif以降を「currentの中身が定義されていない状態ではなかったら」と
    理解していたために微妙なズレがありました。

    キャンセル

  • 2017/10/05 14:50

    「型キャスト」という言葉をご存知ですか?
    javascript では暗黙の「型キャスト」が行われます。
    undefined は 真偽値にキャストされると false になります。

    https://developer.mozilla.org/ja/docs/Glossary/Falsy

    キャンセル

  • 2017/10/05 14:53

    ん?

    > 今まではif以降を「currentの中身が定義されていない状態ではなかったら」と理解していた

    これは合ってますよ。undefined とは、大雑把に言うと定義されていない時の値です。

    キャンセル

  • 2017/10/05 14:57

    わ・・・わかった!!!
    たぶん大丈夫だと思います!!
    またわからないところがあったらよろしくお願いします!
    ありがとうございました!

    キャンセル

+3

.page.up{z-index:2;}
.page{z-index:1;}


を指定しておいて、upクラスを付け替えるのはどうでしょうか?

document.addEventListener('click',function(e){
  var t=e.target;
  if(t.nodeName==='A'){
    Array.prototype.map.call(document.querySelectorAll('#tab_content1 .page'),function(i){
      i.classList.remove('up');
      if('#'+i.id===t.getAttribute("href")){
        i.classList.add('up');
      }
    });
  }
});
<div class="js-tabs">
  <ul id="tab_menu1" class="tab_menu">
    <li><a href="#page1-1">Page 1</a></li>
    <li><a href="#page1-2">Page 2</a></li>
    <li><a href="#page1-3">Page 3</a></li>
  </ul>
  <div id="tab_content1" class="tab_content">
    <div id="page1-1" class="page up">
      Page 1
    </div>
    <div id="page1-2" class="page">
      Page 2
    </div>
    <div id="page1-3" class="page">
      Page 3
    </div>
  </div>
</div>

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.37%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • JavaScript

    21543questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。