はじめに、今回はJSONにあまり触れていません!
WordPress等で日々サーバサイドやデータベースの便利さを感じつつ…そういえばJSとよく似たJSON(ジェイソン)というデータ形式があったな。これを使えばクライアントサイドでもグラフやゲームやインタラクティブコンテンツやらを作れそうだ、と思い浮び調べ始めたところ…前提知識不足すぎて知りたいことが数珠つなぎ!数週間も沼にハマってました。*1
未だJSON未到達なのですがw まずはJSの多次元配列でやりたいことを実現してみた。 これを礎に次回こそはJSON体験したひっっ!!
※目次:
- HTMLではっぴいえんどのアルバムを入力したった!
- 配列、連想配列、多次元配列
- 多次元配列にはっぴいえんどのアルバム情報を入れる
- HTMLの中身を空にする。
- 配列のデータをDOMに入れる
- 各アルバムのデータを一つの配列に統合
- アルバム枚数分ループしながら配列データをDOMに入れる!
- 最後に:配列とJSONはよく似た兄弟
※参考:ネイティブJSやってみたシリーズ
qiita.com
HTMLではっぴいえんどのアルバムを入力したった!
まずは手頃なところで、アルバム3枚で解散した「はっぴいえんど」の情報をHTMLで表現。大好きなバンドです。*2
コードはこんなです。
<h1 class="bandname">はっぴいえんど</h1> <div class="spec"> <section class="album"> <h2 class="title">はっぴいえんど</h2> <p class="release">1970/8/5</p> <ol class="track"> <li>春よ来い</li> <li>かくれんぼ</li> <li>しんしんしん</li> <li>飛べない空</li> <li>敵タナトスを想起せよ!</li> <li>あやか市の動物園</li> <li>12月の雨の日</li> <li>いらいら</li> <li>朝</li> <li>はっぴいえんど</li> <li>続はっぴ-いいえ-んど</li> </ol> </section> <section class="album"> <h2 class="title">風街ろまん</h2> <p class="release">1971/11/20</p> <ol class="track"> <li>抱きしめたい</li> <li>空いろのくれよん</li> <li>風をあつめて</li> <li>暗闇坂むささび変化</li> <li>はいからはくち</li> <li>はいから・びゅーちふる</li> <li>夏なんです</li> <li>花いちもんめ</li> <li>あしたてんきになあれ</li> <li>颱風</li> <li>春らんまん</li> <li>愛餓を</li> </ol> </section> <section class="album"> <h2 class="title">HAPPY END</h2> <p class="release">1973/2/25</p> <ol class="track"> <li>風来坊</li> <li>氷雨月のスケッチ</li> <li>明日あたりはきっと春</li> <li>無風状態</li> <li>さよなら通り3番地</li> <li>相合傘</li> <li>田舎道</li> <li>外はいい天気</li> <li>さよならアメリカさよならニッポン</li> </ol> </section> </div>
※参考:【HTMLの基本】書ける前に読む!HTML、CSS、JSの書式-2 - クモのようにコツコツと
これ、3枚だからまだそんなに苦にならないけど、例えばビートルズ*3の全アルバムの場合は十数枚あるんでもっとキツそうです。ホワイトアルバムなんて2枚組ですからね。。
HTMLの何がきついって<li>曲名</li>
を複製して、両サイドのタグを間違えて消さないように気を使いながら文字をペーストすることですよね!!
配列、連想配列、多次元配列
この曲名をJSの配列に移してみましょう。配列はナンバリングでアクセスする「配列」とキー名でアクセスする「連想配列」の2種類がありますね。
※参考:配列とは
【JSの基本-前編】書ける前に読む!HTML、CSS、JSの書式-4 - クモのようにコツコツと
//配列 var 配列名 = [値, 値, 値]; //アクセス 配列名[0] //連想配列 var 連想配列名 = {キー: 値, キー: 値, キー: 値}; //アクセス 連想配列名[キー]
配列は[]
カッコ、連想配列は{}
カッコです。配列のカウントは1ではなく0から始まります。[0]
は1番目という意味。
配列の中に配列を入れ子できて、これを「多次元配列」と言います。
//多次元配列 var 配列名 = [ 値, [値, 値, 値], 値 ]; //アクセス 配列名[1][0]
2番目のキーの中の1番目のキーの値にアクセス。エクセルでいう「行」と「列」みたいなイメージです。
連想配列の場合はこうなります。
//多次元連想配列 var 連想配列名 = { キー: 値, キー: { キー: 値, キー: 値, キー: 値 }, キー: 値 }; //アクセス 連想配列名[キー][キー]
これもキーの中の連想配列のキーの値にアクセス。
また、配列と連想配列の混合もできます。
//多次元配列(混合) var 配列名 = [ 値, {キー: 値, キー: 値, キー: 値}, 値 ]; //アクセス 連想配列名[1][キー]
配列2番目の中のキーの値にアクセス。
多次元配列にはっぴいえんどのアルバム情報を入れる
1枚目のアルバムはこのようになります。
最初のHTMLに比べるもタグが無いため、見た目がスッキリ。修正もしやすそうです。
//アルバムデータ var album1 = { title: "はっぴいえんど", release: "1970/8/5", track: [ "春よ来い", "かくれんぼ", "しんしんしん", "飛べない空", "敵タナトスを想起せよ!", "あやか市の動物園", "12月の雨の日", "いらいら", "朝", "はっぴいえんど", "続はっぴ-いいえ-んど" ] }
- 変数
album1
の中に連想配列タイトルtitle
、発売日release
、曲名track
を入れる。 - 曲名
track
の値には配列で11曲の曲名を入れる
HTMLの中身を空にする。
データをすべて配列に写したら、HTML内の情報は空っぽにしてしまいましょう。
<h1 class="bandname">はっぴいえんど</h1> <div class="spec"> <section class="album album1"> <h2 class="title"></h2> <p class="release"></p> <ol class="track"></ol> </section> <section class="album album2"> <h2 class="title"></h2> <p class="release"></p> <ol class="track"></ol> </section> <section class="album album3"> <h2 class="title"></h2> <p class="release"></p> <ol class="track"></ol> </section> </div>
曲名.track
はol
要素ですが中のリストli
は空にしました。アルバムによって曲数が違うので、曲数分ループしながら追加しようと思います。
配列のデータをDOMに入れる
次に配列データの内容をDOMに入れ込みます。
※参考:DOMとは
【JSの基本-前編】書ける前に読む!HTML、CSS、JSの書式-4 - クモのようにコツコツと
このように書きます。
//曲名(1枚目) var album1Title = document.querySelector('.album1 .title'); album1Title.innerHTML = album1.title; //発売日(1枚目) var album1Release = document.querySelector('.album1 .release'); album1Release.innerHTML = album1.release; //曲名(1枚目) var album1Track = document.querySelector('.album1 .track'); //(1枚目の曲数分) for (var i=0; i < album1.track.length; i++) { var list = document.createElement('li'); list.innerHTML= album1.track[i]; album1Track.appendChild(list); }
- 変数
album1Title
で.album1 .title
セレクタを取得し、その中に配列album1
のtitle
キーの値を入れる(innerHTML
) - 変数
album1Release
で.album1 . release
セレクタを取得し、その中に配列album1
のrelease
キーの値を入れる - 変数
album1Track
で.album1 . track
セレクタを取得し、その中に配列album1
のtrack
キー内の配列数(曲数)分ループ - 変数
list
でli
要素を作成(createElement ()
)する。 - 変数
list
に配列album1
のtrack
キーのi
番目の値を入れる - リスト(変数
list
)を 変数album1Track
の最後に追加(appendChild()
)
※参考:ループ(反復)とは
【JSの基本-後編】書ける前に読む!HTML、CSS、JSの書式-5 - クモのようにコツコツと
でけた!!
「HTML」「JS」タブを切り替えてみてください。HTMLの中身は空っぽなのにJSの配列のアルバム1枚目のデータが表示されていますね!
しかしながら、アルバム2枚目、3枚目を増やすときに、このコードをコピペして、変数名を打ち替えて…ふーむ、この量産はまた冗長の「にほひ」がしてきますね。。ビートルズ全アルバムなんか作ってらんないし、修正が生じたら修正箇所が倍々ゲームです。
各アルバムのデータを一つの配列に統合
まず、アルバムデータ自体も変数album1
といちいち番号を打つのは手間です。打ち間違わないよう神経を使うしね。
そこで、全体を配列の中にに入れてみます。外側に全体を包む変数albums
を作り、この中に配列を入れます。
//アルバムデータ var albums = [ 1枚目内容, 2枚目内容, 3枚目内容]
配列の値一つ一つは連想配列になりますね
//アルバムデータ var albums = [ {1枚目:内容, 1枚目:内容, 1枚目:内容}, {2枚目:内容, 2枚目:内容, 2枚目:内容}, {3枚目:内容, 3枚目:内容, 3枚目:内容}, ]
全体としてはこうなります。
//アルバムデータ var albums = [ { //1枚目 title: "はっぴいえんど", release: "1970/8/5", track: [ "春よ来い", "かくれんぼ", "しんしんしん", "飛べない空", "敵タナトスを想起せよ!", "あやか市の動物園", "12月の雨の日", "いらいら", "朝", "はっぴいえんど", "続はっぴ-いいえ-んど" ] }, { //2枚目 title: "風街ろまん", release: "1971/11/20", track: [ "抱きしめたい", "空いろのくれよん", "風をあつめて", "暗闇坂むささび変化", "はいからはくち", "はいから・びゅーちふる", "夏なんです", "花いちもんめ", "あしたてんきになあれ", "颱風", "春らんまん", "愛餓を" ] }, { //3枚目 title: "HAPPY END", release: "1973/2/25", track: [ "風来坊", "氷雨月のスケッチ", "明日あたりはきっと春", "無風状態", "さよなら通り3番地", "相合傘", "田舎道", "外はいい天気", "さよならアメリカさよならニッポン" ] } ]
これで「i
番目のアルバム」と配列数をカウントしながらループ処理ができると良さげです。
HTML上のテンプレも先ほどの曲名リストli
の様にループで増やせばいいので1枚分にしちゃいましょう。
<h1 class="bandname">はっぴいえんど</h1> <div class="spec"> <section class="album"> <h2 class="title"></h2> <p class="release"></p> <ol class="track"></ol> </section> </div> </section>
さらにコンパクト!
アルバム枚数分ループしながら配列データをDOMに入れる!
まず先ほどのHTMLのテンプレート.album
一式をアルバム枚数分-1枚ループして複製したい。
(もともとテンプレが1つあったので、アルバム枚数分だと1つ多くなってしまった)
//外枠アクセス var spec = document.querySelector('.spec'); //テンプレ複製 //(アルバム枚数-1枚) for (var i=1; i < albums.length; i++) { var clone = spec.firstElementChild.cloneNode(true); spec.appendChild(clone); }
- 変数
spec
に.spec
セレクタを取得 for
文で配列albums
の配列をアルバム枚数-1枚分ループ(変数i
のカウントを1
から始める)*4- 変数
clone
に変数spec
の最初の子要素firstElementChild
(.album
セレクタ)を複製(cloneNode(true)
)する*5 - 変数
spec
に変数clone
を最後に追加する(appendChild()
)
これでテンプレがアルバムと同じ3つに増えた。
次に繰り返し使うセレクタを変数に入れて取得しよう。
querySelectorAll
は複数ある要素を全て取得し、配列に入れる。
//タイトル、発売日、曲名アクセス var specTitle = document.querySelectorAll('.title'); var specRelease = document.querySelectorAll('.release'); var specTrack = document.querySelectorAll('.track');
- 変数
specTitle
にタイトル.title
セレクタを取得 - 変数
specRelease
に発売日. release
セレクタを取得 - 変数
specTrack
に曲名. track
セレクタを取得
この取得は最初のテンプレ複製後に実行しないともともとの1つしかない挙動になったので注意。
最後にDOMにデータを入力。for
文のアルバム枚数カウント「i
枚目」がカギ!
//アルバムデータ入力(アルバム枚数分) for (var i=0; i < albums.length; i++) { //タイトル入力 specTitle[i].innerHTML = albums[i].title; //発売日入力 specRelease[i].innerHTML = albums[i].release; //曲名入力(曲数分ループ) for(var t=0; t < albums[i].track.length; t++) { var list = document.createElement('li'); list.innerHTML= albums[i].track[t]; specTrack[i].appendChild(list); } }
for
文で配列albums
の配列数(アルバム数)分ループ- タイトル:変数
specTitle
のi
番目に配列albums
のi
番目のtitle
キーを入れる(innerHTML
) - 販売日:変数
specRelease
のi
番目に配列albums
のi
番目のrelease
キーを入れる(innerHTML
) - 曲名:
for
文で配列albums
のi
番目のtrack
キーの配列数(曲数)分ループ。なお、曲数カウントの変数はt
にしてみた。 - 変数
list
でli
要素を作成(createElement()
) - 変数
list
に配列albums
のi
番目のtrack
キーのt
番目の値を入れる(innerHTML
) - 変数
specTrack
のi
番目の最後に変数list
のリストを追加(appendChild()
)
でけた!!!
「HTML」「JS」タブを切り替えてみてください。HTMLの中身は空っぽのままJSの配列のアルバム3枚目までのデータが全部表示されていました!
最後に:配列とJSONはよく似た兄弟
冒頭に触れたJSONですが、こんな書式です。
//多次元配列 var 連想配列名 = { キー: 値, キー: { キー: 値, キー: 値, キー: 値 }, キー: 値 }; //JSON { "キー": 値, "キー": { "キー": 値, "キー": 値, "キー": 値 }, "キー": 値 };
ほとんどJSの配列と一緒じゃないですか!違うのはキー名がタブルコーテーション" "
でくくられている部分。ちなみにJSONではシングルコーテーション' '
はNGらしい。
外部ファイルとして独立し、拡張子は.json
になります。これによってPHPなどのサーバサイドからもアクセスや操作が容易になります。
データにするとHTMLテキストよりも拡張性や再利用性が高まるわけです。
次回は外部JSONファイルとして切り出して、アクセスしてみたく思います!昔からJSONはjQueryならシンプルな書式でアクセスできたようだけど、触る機会はなかった。
そして調べたところ、最近は他にもいろんな書き方が増えてきたようです。どれが一番ベターなのか検証したい。それでは!
※参考:ネイティブJSやってみたシリーズ
qiita.com