jQuery初学者がつまづくポイントとして、サンプルを見て「なんでそれで動くのか分からない」、というのがあると思います。「jQueryでアコーディオンメニューを作りたい」と思ったとき、検索すればサンプルはたくさん出てきます。しかし、セレクタ
は分かる、on
でイベントハンドラ
、など文法は分かっているのに、意味が分からない、自分で書ける気はしない、という感じです。
今回は、こちら↓のサイトで紹介されているアコーディオンを例に、jQueryの理解を深めるための、サンプルの読み解き方について書いてみたいと思います。
対象の読者
- JavaScript/jQueryの基本的な文法がわかる人。
- 一般のサイトでサンプルを見て、コピペして動かすことはできるがなんで動くのか分からない人。
- 分かるようになるためのコツが知りたい人。
サンプルを読み解く流れ
ここでは以下のような流れでサンプルを読み解いていきます。
- サンプルのどこに着目して理解を深めたいか決める
- 関係ない部分を削る
- console.log()で処理の一部を取り出して確認する
1つ1つ見ていきましょう。
サンプルのどこに着目して理解を深めたいか決める
上記サイトの「アコーディオン、シンプル版」を例に説明していきます。Codepenでサンプルが公開されています。サンプルそのままの状態のものがこちら↓です。
See the Pen アコーディオン、シンプル版 by 125naroom (@125naroom) on CodePen.
Codepen↑の、この↓部分をクリックすると、大きな画面で表示されます。この後の説明に従って、実際にCodepenの画面でコードをいじってみてください。
大きな画面で開いたら、実際に見出しをクリックして開閉してみましょう。
なお、ソースコードの行数は以下のようになっています。
- HTML:31行
- CSS:171行
- JavaScript:10行
「どこに着目して理解を深めたいか決める」ために、このサンプルはどのような機能の集まりでできているかをじっくり観察します。例えば、以下のような点はすぐに分かるでしょう。
- 見出しをクリックすると「中身です」が表示される。
- 再度見出しをクリックすると「中身です」が消える。
「アコーディオン」として最低限の機能ですね。もう少し詳しく、実装に近い観点でみていきましょう。
- 見出しをクリックすると、対応する「中身です」が表示される。対応しない「中身です」は変化しない。
- 「中身です」をクリックしても閉じない。
- 「パッ」と表示/非表示になるのではなく、「滑らかに」開閉する。
- 開閉の際、他の見出しが下に押し下げられる。
「それって当たり前...」と思ったでしょうか。しかし自分でJavaScriptを書いてみると、なぜか上記のような細かい点がうまく行かないことも多いものです。この記事の最後にNG集を載せていますので、よくソースコードを見比べて、なぜうまく行かないのかも観察してみると良いでしょう。
さらに、アコーディオンが「開閉する」ことには直接関係ない、飾りのような部分も含めて、以下のような点も意識しておくと良いです。これは次のステップで、「関係ない部分を削る」ために必要な作業です。
- 見出しにマウスを当てるとマウスカーソルが手の形になる。
- 閉じている見出しには「+」、開いている見出しには「ー」が表示されている。
- 開閉の際、「+」「ー」が回転している。
- 見出しがそれぞれ別の色になっている。
- 見出しにマウスを乗せると見出しの色が少し白っぽくなる。離すと元に色に戻る。
ここまで分解できたら、どこに着目するか決めましょう。「アコーディオン」なので、「開閉」の理解を深めたい、飾りの部分(「+」「ー」ボタンの部分など)は今回は置いておこう...といったことですね。
関係ない部分を削る
さて、今回はアコーディオンの「開閉」に関するところに焦点を当てたいと思いますので、関係ない部分を削っていきます。JavaScript/jQueryに関する記事ですが、ここではCSSもガンガン削っていきます。
デベロッパーツールを使いますので、開き方や要素の調べ方については、こちら↓の記事のデベロッパーツールを開く
〜デバイス表示
あたりまでをご覧ください。
アコーディオンの外のリンク
この部分(1,2)
はサンプルサイトへのリンクなので、「class="_a"」「.a」(3)
に関連するところを削ります。また、ご丁寧にも「以下は不要です。」(4)
とのことなので、これも削ってみましょう。
見出しごとの色をなくす
まず「見出しの色はbackground
だろう」と見当をつけます。デベロッパーツールで見出しを選択し、フィルタでbackground
と入力すると、.s_01 .accordion_one .accordion_header
でbackground-color: #db0f2f;
を設定していることが分かります。
cssからbackground-color: #db0f2f;
を検索して削除します。この時、color: #fff;
も合わせて消します。消さないと白地に白文字になって見えなくなってしまうためです。なお、Codepenでは自動的にプレビューが更新されます。
同様に、残りの背景色(1,2)
も消していきます。空{}
になった部分は消して良いです。
マウスが乗った時の色の変化をなくす
マウスが乗った時の記述はcssのhover
だろうと見当をつけます。hover
のついた部分を消していきます。
右の「+」「ー」アイコンをなくす
デベロッパーツールで(1)
部分を確認すると、(2)
部分であることが分かります。HTMLの(3)
該当部分を消していきます。3箇所あります。
その他見栄えに関する部分をなくす
width
, height
, margin
, padding
, font-size
, font-weight
, border
(1)
などは見栄え上のことで、開閉には関係ないだろうと見当をつけ、消していきます。display
, position
, z-index
(2)
あたりはいったん残しておきます。
いったん、この状態のCodepenを置いておきます↓。
See the Pen アコーディオン - 削る1 by yymmt (@yymmt) on CodePen.
cssを削ったことで関係なくなったJavaScript部分をなくす
こちら↓ではtoggleClass
でopen
クラスを付けたり外したりしていますが、すでにopen
クラスはHTMLにもCSSにもありませんので、JavaScriptからも消してしまいましょう。
古い記述をなくす
$(function(){
と});
は、JavaScriptを<head>
に書くことが慣習だった時代の名残りと思って良いでしょう。最近ではJavaScriptは<body>
の末尾に書くことが多く、その場合はこの記述は不要です。
ついでにコメントも消して、こう↓なりました。
See the Pen Untitled by yymmt (@yymmt) on CodePen.
判断に困ったところは1行ずつ消して動作を確認する
position: relative;
(1)
は、「相対的な位置」に関する記述、
z-index: +1;
(2)
は、「表示の前後」に関する記述、
transition-duration: 0.2s;
(3)
は、「滑らかにCSSを変化させる」記述です。いずれもアコーディオンに関係しそうな感じはありますが、消してみると変わらず開閉しました。
display: none;
は、「非表示」にしておくための記述です。消してみると、「中身です」が最初から表示されてしまいました。これは残しておきましょう。
HTMLの中で、CSSとJavaScriptに出てくるクラス名を確認します(青線部分)。出てこないクラス名は消してよいです。また、今回のCSSとJavaScriptではタグ名による選択がないので、クラスがなくなったタグ(赤線部分)も消してよいです。
冗長な記述をなくす
.s_01 .accordion_one .accordion_inner
とは、
「s_01
クラスを持つ要素の子孫要素の中で、
accordion_one
クラスを持つ要素の子孫要素の中で、
accordion_inner
クラスを持つ要素」のことです。
単に.accordion_inner
とだけ書いても同じですね。
JavaScriptの.s_01 .accordion_one .accordion_header
も同様に、.accordion_header
にします。
だいぶ減りましたね。
See the Pen アコーディオン - 削る3 by yymmt (@yymmt) on CodePen.
いったんここまでのまとめ
ここまでで、
- サンプルのどこに着目して理解を深めたいか決める
- 関係ない部分を削る
を行いました。その結果、ソースコードの行数は、
- HTML:14行
- CSS:3行
- JavaScript:3行
と、かなり減りました。「読める気がする」感がだいぶ増したのではないでしょうか。
console.log()で処理の一部を取り出して確認する
JavaScriptで console.log(●●●●)
と記述することで、デベロッパーツールに●●●●
部分を出力することができます。サンプルプログラムの一部を出力することで、理解が深まります。
準備
再度、「見たいところ以外を削ったアコーディオン」を見てみましょう。
See the Pen アコーディオン - 削る3 by yymmt (@yymmt) on CodePen.
↑
の↓
Edit on Codepen
をクリックすると、大きな画面で表示されます。
また、プログラムのボリューム的に、この↓
レイアウトの方が見やすいかもしれません。
Codepenでデベロッパーツールを開くとこのようになります。今回は「コンソール」(1)
を開いておきましょう。いろいろと赤文字(2)
が表示されますが、Codepen側の都合で何か出力しているものと思われますので、「コンソールを消去」(3)
で消しておきましょう。
$('.accordion_header')を出力してみる
「$('.accordion_header')
は、accordion_header
クラスを持つ要素を選択するjQueryの関数である」、ということは知ってはいても、「出力して」「目視した」ことはあるでしょうか。
Codepenの画面で、JavaScriptの1行目に、console.log($('.accordion_header'));
(1)
と入力し、そのまま数秒待ってみましょう。ゆっくり打っていると、打ちかけの状態で実行されてしまいエラー表示になることがありますが、落ち着いて再度「コンソールを消去」して、続きを打ちましょう。 コンソールに何やら(2)
表示されます。▼(3)
をクリックすると、詳細が表示されます。
0: div.accordion_header
部分にマウスを当てると、見出しがハイライトします。$('.accordion_header')
が「見出し」を選択できていることを確認したことになります。
$(this)を出力してみる
console.log($(this));
を追記して、見出しをクリックしたところです。クリックした見出しだけが選択できていることを確認することができます。
console.log($(this));
を追記するのは、元から記述されていた、
$(this).next('.accordion_inner').slideToggle();
の直前が良いです。
変数は中身がどんどん変わったり、スコープと言って、変数の使える範囲が決まっていたりします。
this
を確認したければthis
の直前でconsole.log
するのが良いです。
(なお、そもそもthis
は文脈によって意味が変わってしまうので、自分で書くときはe.target
などの方が良いです。)
nextを出力してみる
$(this).next('.accordion_inner')
も見てみましょう。
先ほどの$(this)
も残しておきたいので、先頭に"1:",
"2:",
などつけておくと見やすいです。
$(this)
が、クリックした見出し、
$(this).next('.accordion_inner')
が、クリックした見出しに対応した「中身です」を選択していることを確認することができます。実際に以下の動画のように操作してみましょう。
いったんここまでのまとめ
console.log()
で処理の一部を取り出して確認することで、実際にjQueryがどの要素を選択しているかを視覚的に確認することができました。これにより、
$('.accordion_header').click(function(){
$(this).next('.accordion_inner').slideToggle();
});
というプログラムが、
【見出し】 .click(function(){
【クリックした見出し】 に 【対応する「中身」の要素】 .slideToggle();
});
と、意味を伴って読めると思います。ピリオド.
は適宜てにをは
にして読みましょう。残りの.click
やfunction()
や.slideToggle()
は、元の意味を知らなくても、
【見出し】 を 【クリックした時に以下を実行する】
【クリックした見出し】 に 【対応する「中身」の要素】 を 【開閉する】
と推測できるでしょう。推測できずとも、jQuery slideToggle
などで検索すれば分かりそうです。少なくとも、セレクタ
、click
、function
、this
、next
、slideToggle
を全部調べるよりは、かなりハードルが下がったと思います。
「書ける」ようになるために
ここまで、サンプルの読み解きを解説してきましたが、書けるようになるためのポイントも少し書いておきます。
サンプルを複数探す
今回はslideToggle
で開閉するサンプルでしたが、slideUp
、slideDown
で開閉したり、「すでに開いているかどうか」を判定するためにvisible
を使うなど、様々なパターンがあります。今作ろうとしているものに近いものを探しましょう。
削ったものをコピペ
今回の要領で削ったものを、自分のサイトにコピペしてみましょう。動けばそれでよし。ちょっと見た目を変えたい、という場合も、「削ってない元のサンプル」に手を入れるよりはだいぶやりやすいと思います。
動かない場合
console.log
で1つ1つの動作を確認してみましょう。例えば
$('.accordion_header')
(1)
を
$('.accordion-header')
(2)
と間違えている場合、console.log($('.accordion-header'))
を追記しても要素が出力されず、length: 0
とだけ出力されます。
これにより、$('.accordion-header')
のどこかに間違いがあることがわかります。(今回はハイフン-
とアンダーバー_
を間違えています。)1つ1つ修正していきましょう。
動くけどちょっと違う場合
次のNG集を見てみましょう。わずかな記述の違いで、いろいろな挙動が観察できます。どの記述がどう影響するかを把握しておくと、自分で作ったものが「ちょっと違う」原因も見つけやすくなります。
NG集
冒頭で「アコーディオン」の分析をしたとき、「アコーディオンなんだから当たり前」に見える機能もしっかり観察することをお勧めしました。ここでは、わずかな記述の違いで、いろいろな挙動に変わる(変わってしまう)様子を見ていただければと思います。それぞれ、何が原因か観察してみましょう。(必要であればconsole.log()
などを追記してみましょう。自分で作ったCodepenでなければ修正しても保存されませんので、どんどん修正してみてください。)
- 見出しをクリックすると、対応する「中身です」が表示される。対応しない「中身です」は変化しない。
以下のように実装すると全ての「中身です」が開閉してしまいます。
See the Pen アコーディオン - NG1 by yymmt (@yymmt) on CodePen.
- 「中身です」をクリックしても閉じない。
以下のように実装すると「中身です」をクリックした時にも閉じてしまいます。
See the Pen アコーディオン - NG2 by yymmt (@yymmt) on CodePen.
- 「パッ」と表示/非表示になるのではなく、「滑らかに」開閉する。
以下のように実装すると「パッ」と表示/非表示になります。
See the Pen アコーディオン - NG3 by yymmt (@yymmt) on CodePen.
- 開閉の際、他の見出しが下に押し下げられる。
以下のように実装すると見出しが押し下げられません。
See the Pen アコーディオン - NG4 by yymmt (@yymmt) on CodePen.