最も簡単な折りたたみはDetailsとsummaryですが、同じくらい簡単なjQueryによるDetailsもどきを作ってみます。
このページ内の見出し
折りたたみ
「折りたたみが最も簡単 details と summary についてメモ」で、Detailsとsummaryについて書きました。実際、最も簡単です。スクリプトも要らず、簡素なHTMLとCSSだけで何とかなります。
こんな感じのdetailsとsummaryです
理解しやすく簡単ですが、アニメーション効果を付ける場合にはわずかに面倒なCSSを書く必要がありますし、閉じる時には動きの効果が得られません。そういう弱点もあります。
この弱点は微妙に致命傷で、気にしなくていいんですけど気にし出すと止めどがなくなります。
そこで、近頃使いやすくなったjQueryを使って簡素な折りたたみを作ってみようとちょっとやってみました。
目的と目標は、detailsとsummaryと同じ程度の使用感、そして簡単に作れて手軽に使えることです。ちょっと口を滑らしたことについてのコラムを兼ねてこんな感じの完成品です。
↓
近頃使いやすくなったjQueryとは何のことか。それは、WordPressが新しいバージョンのjQueryの読み込みを標準化した(しようとしている)ことによります。これにより、環境ごとにバラバラだった読み込み有無やバージョン違いなどを吸収してしまうことになりました。「標準で新しいバージョンのjQueryが読み込まれている」というみんなに共通する前提を担保することで、面倒な調査や手続きや不穏な気持ちがいらなくなったわけです。ということでこれまで事前準備や心構えが面倒で避けていたjQueryを使っていく方向に自然になっていきます。
WordPressでjQueryを使うこと
超素人がjQueryについてググると、まずたいていライブラリの読み込みから話が始まっていて、そこで読み込むバージョンだのダウンロードだのクラウドだのとわけのわからない話がてんこ盛りで「もういいやバイバイ」となりますが、WordPressでの使用だとそういうのは一切関係ありません。もう読み込まれてます。
ですから準備はいりません。スクリプトだけ書きます。大層な仕組みでもないから書く場所は使いたいページテンプレート内でもOK。でも利便性を考えて専用phpファイルを作りそれを使用するテンプレートで読み込むのがいいかもしれません。
あと、余所から参考にしてコピペするときなんかの書き方で「$( )」というこの「$」は「jQuery」と書き変えます。理由はそうしないとwordpressでは動かないから。まあ、「$」なんて変数みたいで混乱するから「jQuery」と書いたほうが見た目もわかりやすいです。
details と summary と違って、動きのために高さを気にしなくていいというのはいいです。しかもこれ一度仕込んでしまうとHTMLはdetailsよりシンプルです。箱ふたつ(クリックするタイトル部分と中身の二つ)だけで成り立ちます。
では行きます。
js-details
さて折りたたみがもっとも簡単なdetailsとsummaryを気に入って多用してきた筆者にとって、このHTMLの形がわりと染み込んでいます。筆者につられて同じようにdetailsをよく使う編集人にも馴染んでいます。だからjQueryで同じようなものを作ったときも似た形にしたい。そこで、こうしてみました。
HTML
<div> <div class="js-summary">summaryみたいな部分</div> <div class="js-container">コンテナ部分。つまり中身。隠されていてsummaryクリックで展開する部分。</div> </div>
HTMLはこんな形です。
detailsでは大枠を <details> で括りますがjQuery版では括る必要ありません。でも括りたければdivでも何でもいいので括ります。
detailsとsummaryはHTMLタグですが、jQuery版では要素を指し示すセレクタが対象となります。
大事なルールはsummaryもどきの要素とコンテナもどきの要素が並んでいるということです。これを専門用語で隣接しているといいます。上の例では .js-summary のかたまりと.js-containerが隣接しています。隣接が大事です。なぜなら、そういうスクリプトだからです。「クリックした固まりに隣接した固まりが開いたり閉じたりする」というスクリプトです。
スクリプト
jQuery(function(){ jQuery('.js-summary').each(function(){ jQuery(this).on('click',function(){ jQuery(this).toggleClass('open'); jQuery("+.js-container",this).slideToggle(300); return false; }); }); });
この例では .js-summary というかたまりと .js-containerというかたまりがあって、.js-summaryをクリックしたら”open”というclassが付与されて、隣接する.js-containerが開きます。というかトグルですので消えていたら表示されます。
class”open”を付与するのはオマケ的なことで、開閉には直接関係ありません。開いた状態と閉じた状態でアイコンを変えたいから付け足します。
この数行のスクリプトは運営上の前提に頼りきっています。”open”というclassが付与されることも、表示・非表示がトグルなのも、あらかじめ仕込んであるHTMLとCSSを前提としているからこそ単純な形に収まっています。
つまり HTML と CSSでこうなっていることが前提です。
- .js-summaryに初期状態で “open” というclassが付いていない
- .js-container は、初期状態で非表示になっている
汎用的に作り込むなら「もし最初からオープンなら」とか「もしコンテナが開いていれば」みたいな状況の条件を付け加え分岐させていくのが筋ですが、面倒なので「最初は必ず閉じている」ことを前提としています。
マイルール前提の簡易な仕組みと、あらゆる可能性とエラー処理を考慮しなければならない汎用的な仕組みとでは、その作り込みに大きな違いがありますね。
簡易とは言え、このスクリプトには賢人の知恵が詰まっています。例えば最初にeachしていることや、this の使い方に並みじゃない英知が詰まっています。もちろんこれを書いた天才は私じゃありませんで、このアイデアをお見かけして拝借しただけです。つまりパクりです。にもかかわらずどこから引用したか元記事の記録もすでになくて示せないという非礼。すいません。本当にすいません。
CSS
.js-summary { cursor: pointer; } .js-summary:before { content: "\f139"; font-family: "dashicons"; } .js-summary.open:before { content: "\f140"; } .js-container { display: none; }
CSSですが、装飾は取っ払って基本的なことだけですがこんな感じです。
.js-container が初期状態で「display: none 」であることが重要ですね。最初隠れていて、トグルにより表示されます。
このCSSで引っかかるのはアイコンフォントにdashiconsというものを使用しているところでしょうか。
dashicons
dashiconsはwordpressのダッシュボード内に使われているアイコンフォントです。これを表立っても使っているのでこう書いていますが、他のアイコンフォントを使っているとか、画像を使うとか、人それぞれな箇所です。
detailsのsummaryのような三角印が最も直感的で判りやすいのでそれに合わせています。
dashiconsをブログで使用するには、functions.phpにこう書いて読み込んでから使うと良いそうです。
add_action( 'wp_enqueue_scripts', 'load_dashicons' ); function load_dashicons() { wp_enqueue_style( 'dashicons' ); }
dashiconsのアイコンフォントはこちら。
https://developer.wordpress.org/resource/dashicons/
いろいろアイコンフォントを使ってみたこともありましたが、数が多いと選ぶのが面倒だし、使用をやめたいときのダメージもあるし、無難で面倒のないWordPressのdashuiconsを使うことで落ち着きました。
そんなわけでjQuery でかんたん折りたたみでした。このような形になります。
単にふたつの固まりが並んでいて、
.js-summary
と
.js-container です。こちらjs-containerは初期状態でdisplay:noneです。
固まりはdivでも ul li でも何でもOK。
.js-summaryをクリックしたらトグルで隣接コンテナが開き(表示され)ます。
オマケでsummaryにopenクラスが付けてアイコンを変化させています。
スライドトグルにclass名を付与した基本型は以上です。が、この記事には続きがあります。
クリックする固まり、detailsでいうところのsummaryにあたる部分ですが、ここが単に折りたたみボタンであれば問題ないのですが、リンクテキストを置きたいという欲望もあるわけです。
続きは次ページ
詳しいご説明ありがとうございます。初歩的な質問で申し訳ないのですが、ハッシュタグで別ページから飛んできた際、js-containerを開いて表示したいのですがどうすれば良いでしょうか?
ここでは、jQueryでターゲットに class を付けたり外したりしているだけで、挙動はCSSが受け持っています。投稿の中でも書いているとおり、汎用的な動きに関して触れていません。
条件に応じて初動を変化させようとすれば、デフォルトで “open” classを付けるつけないを、細かく制御してやる必要があります。
どこかから飛んでくるのなら、飛ばす段階で「リンク先のターゲットのclassを制御する」ということを行わなければなりません。
そのやり方は・・・難易度高いですね。私には到底答えられません。cookieを使って条件分岐させるのが良いかもしれないですね・・どうでしょう。
リンク先の特定要素にアプローチする方法を検索しまくって、是非よいやり方を見つけてください。見つけたら教えてください!