JavaScriptでDOM操作してみる
JavaScript勉強番外編。
本編(の前回の記事)はこっち micche-labo.hatenablog.com
アコーディオンメニューでよくある、クリックしたら開いて、クリックしたら閉じる、のような動きをJavaScriptで実装したらどうなるのか、ということを調べてみました。
まだ未完成なんですが、一旦やりたいことの第一歩は進んだ気がしたので記録。
できたのはこれ。
See the Pen クリックイベントでアコーディオンメニューその1 by Micche (@micche) on CodePen.
ひとつめの項目しかアコーディオンになってません。
とりあえずここまでのJavaScriptの挙動をメモ。
DOM操作-クリック、トグル
今回は
- クリックで出てくる
- もう一度クリックで隠れる
といった部分はCSSで実装し、JavaScriptには
- クリックしたら
- クラスのつけはずし
をしてもらいます。
HTMLとCSSで見た目を作り、整える
プログラムを書く前に、まずはHTMLとCSSのそれぞれの記述。
HTML
<ul class="accordion"> <li class="menu js-menu">アコーディオンメニュー <ul class="child"> <li>子要素</li> <li>子要素</li> <li>子要素</li> </ul> </li> <li class="menu js-menu">アコーディオンメニュー2 <ul class="child"> <li>子要素2</li> <li>子要素2</li> <li>子要素2</li> </ul> </li> <li class="menu js-menu">アコーディオンメニュー3 <ul class="child"> <li>子要素3</li> <li>子要素3</li> <li>子要素3</li> </ul> </li> </ul>
とりあえず三つアコーディオン作ります。
CSS
* { margin: 0; padding: 0; } body { font-size: 16px; letter-spacing: .05em; } /*ここからアコーディオンのスタイル*/ ul { list-style: none; } .accordion { display: flex; flex-direction: column; width: 100%; } .menu { width: 100%; background-color: pink; text-align: center; cursor: pointer; line-height:2em; transition:all .3s; position:relative; } .menu:hover, .menu:active, .menu.is-active, .is-open li:hover{ background-color: palevioletred; color: white; } /*はじめは非表示*/ .child { text-align: center; line-height: 0; height: 0; width:100%; overflow: hidden; opacity: 0; transition: all .3s; /*出てくる位置*/ position:absolute; top:1.5em; left:0; /*出てくる要素を一番上に*/ z-index:999; } /*クラス付与されたら表示*/ .is-open{ line-height: 2em; height: calc(2em * 3); /*3項目なので×3*/ color:#333; opacity: 1; top:2em; /*親要素の高さ分下げる*/ left:0; } .is-open li{ border-top:1px solid black; background:pink; transition:all .3s; } /*PC用アコーディオンメニュー横並び指定*/ @media screen and (min-width:760px) { .accordion { flex-direction: row; } }
CSSには、<li class="menu js-menu">
につける用の.is-active
と、<ul class="child">
につける用の.is-open
を追加しておきます。
これで準備OK。
今の状態は多分こんな感じ。
まだクリックしても何もおこりません。
JavaScript部分を書く
ではJavaScript部分を書いていきます。
順序は、
- 要素の取得
- 取得した要素でクリックイベントを作る
- クリックイベント内でタグのつけ外しを指示する
といった感じ。
1.要素の取得
今までJavaScriptの勉強で行ってきた、変数に格納ってやつをやっていいます。
初回のコレ micche-labo.hatenablog.com
const ul = document.querySelector('.js-menu'); //.js-menuの要素を取得 const li = document.querySelector('.child'); //.childの要素を取得
DOM操作についてはまだ全然勉強できてなんですが(そこ重要)、なんとかググってこうなりました。
それぞれ説明すると、
document
は、html
内を指します。querySelector()
は、html
内のセレクターを指します。()
内にタグ・id・クラスを入れてあげることで、機能します。 このとき、document
がないとエラーになるので注意。()
に取得したいidやclass、タグ名を''
でくくって書く。 例:('#menu');
、('.child');
、('ul');
など。
補足
documentには変数を入れることも可能。
const ulItem = document.querySelector('ul');
で一旦ul
を取得。
そのあと、ulItem.querySelector('.js-menu');
でul
内にあるjs-menu
クラスのついた要素を取得している。
POINT
querySelector
はたくさん一致する要素がある場合、一番初めの要素のみを取得する。
今回はひとつめのアコーディオンの要素のみ取得しているので、ほかのふたつは動かない挙動となっている。
ということで要素を取得できました。
注意
querySelector();
のカッコ内は''
でくくる。class
なら.
、id
なら#
を忘れずにつける。
2.クリックイベントをつくる
以下は関数を省略した形。
ul.addEventListener('click',() => { //ここにトグルイベント実装 }
説明
addEventListener
の()
内には、イベントの種類、関数、イベント伝搬の方式(trueかfalseか)が入ります。
例えば、
ul.addEventListener( 'click', toggleEvent, false );
のように書くことができる。
真ん中のtoggleEvent
は関数名。
なくてもOK。
例1
関数名を書いた場合の記述は、
ul.addEventListener( 'click', toggleEvent, false ); function toggleEvent() { //ここにイベントの処理 //例えば ul.classList.toggle('is-active'); //is-activeというclassをつけ外し }
のように、関数を分けて書くことができる。
例2
関数名を省いた場合。
ul.addEventListener('click', function() { //ここにイベントの処理 }, false);
と書くか、もしくは今回採用した書き方のように、
ul.addEventListener('click', () => { //ここにイベント処理 });
のように書く。(アロー関数使用。)
3.トグルイベントを作る
最後にトグルイベントを作成。
ul.classList.toggle('is-active'); li.classList.toggle('is-open'); //.js-menuクリックで.childに.is-openが付与
最初に定義した、ul
とli
に格納した.js-menu
クラスのついた要素と、.child
クラスのついた要素に対して、クラスをつけ外しするような処理を書いています。
まとめ
まとめるとこう記述します。
//取得 const li = document.querySelector('.child'); //.childの要素を取得 const ul = document.querySelector('.js-menu'); //.js-menuの要素を取得 //クリックイベント。関数は省略。 ul.addEventListener('click',() => { ul.classList.toggle('is-active'); li.classList.toggle('is-open'); //.js-menuクリックで.childに.is-openが付与 });
変数名に「li
」やら「ul
」したのは失敗だったな。
わかりづらい。
とりあえず第一歩ということで。
全部のアコーディオンを開閉できる日は来るのか…!
つづく。