先日トップページの自己紹介欄に物足りなさを感じたので、ボタンを押すと吹き出しがスライドダウンするアニメーションを追加しました。
するとこれを見たブログメンバーから、
クリックして文章を表示みたいなプラグインがあったら入れて欲しい
という要望が出たので自分で機能を実装することにしました。
動作サンプル
CSSかjQueryか
CSS3以降では比較的簡単にアニメーションを実装することができます。
しかし、アニメーションの種類, 時間をカスタマイズしたい場合は使用テーマCocoonの機能『カスタムCSS』に
.box { transition: 500ms; }
のような記述をする必要があります。
しかし「これ他の人はできるのだろうか?」「正直難しいのでは?」といった問題もあります。
そこでHTMLタグのclass属性にオプションも付与する形で実装することにしました。
<a class="btn switch-btn" type="fade" speed="500">ボタン</a>
or
<a class="btn switch-btn effect-fade-500">ボタン</a>
そのような理由で属性値の解析がしやすいjQueryを使用することにしました。
jQuery記述時のエラー回避
テーマエディタでCocoon-Childのjavascript.jsを編集します。
一般に他サイトで紹介されているjQueryの記法を記述すると警告が出ますが、
【Cocoon設定】-> 【その他】
から以下の設定項目でバージョンを変更すると解消されました。
雛形テンプレートの保存
テンプレートの保存はTinyMCE Templatesプラグインを使用します。
今回は『スイッチボタン』という名前のテンプレートを作成しました。
ベータ版実装
動作仕様
「ボタンをクリックすることで非表示だった領域が表示され、ボタン自体は非表示になる」といった動作を実装します。
雛形のテンプレートはこちら。
<div class="switch-wrap"> <a class="btn switch-btn">ボタン</a> <div class="switch-content"> この部分はボタンクリック後に表示されます </div> </div>
.switch-wrap
内に.switch-btn
と.switch-content
を配置しています。使用するclassセレクタは以上3つです。
id指定で実装すれば要素を離すことができますが、テンプレート化した際にidが重複する恐れがあるためclassのみで行います。
CSSの編集
Cocoon-Childのstyle.cssに追記します。
.switch-content { display: none; }
上の設定で.switch-contentを標準で非表示にします。
Cocoon-Childのeditor-style.cssに追記します。
.switch-wrap { background: #f0f8ff; padding: 10px; border-radius: 5px; } .switch-content { background: #e6e6fa; display: block; }
style.cssで.switch-content
を非表示にしたため、エディタ上でも見えなくなってしまうので、style.cssの後に読み込まれるeditor-style.cssで表示するよう上書きしています。
また、切り替え表示部分の領域を可視化するように背景色を設定しました。
javascript.jsの編集
Cocoon-Childのjavascript.jsに以下を追記します。
$(".switch-btn").click(function() { let type = $(this).attr("type"); let speed = $(this).attr("speed"); speed = Number(speed) ? Number(speed) : 500; $(this).hide(); if (type === "fade") { $(this).closest('.switch-wrap').children('.switch-content').fadeIn(speed); } else if (type === "slide") { $(this).closest('.switch-wrap').children('.switch-content').slideDown(speed); } else { $(this).closest('.switch-wrap').children('.switch-content').show(speed); } });
$(this)
はこの場合.switch-btn
自身を指し、$(this).hide()
で非表示にしています。
closest('.switch-wrap')
で.switch-btn
より上の階層の.switch-wrap
を取得し、その子要素となる.switch-content
に処理を行っています。同じ階層に.switch-content
と.switch-btn
を配置できれば.switch-wrap
を必要としないのですが、投稿時に自動でpタグが付与されてしまうためこのような仕様になりました。
アニメーションは最低限の3種類で、フェードイン, スライドダウンは属性で指定します。
オプション例は以下のようになります。
<!-- スライド, 300msの場合 -->
<a class="btn switch-btn" type="slide" speed=300>ボタン</a>
使用方法
基本的にエディタ上部の『テンプレートを挿入』から展開してテキストを編集するだけです。
オプションとして.switch-btn
を持つタグにtype属性, speed属性を付与することでアニメーションの種類/時間を変更できます。この処理はテキストから行います。
TinyMCE Advancedの機能で属性が自動削除される問題
この問題はTinyMCE Advancedを導入している場合に発生し、エディタの表示を『ビジュアル』に戻した際に設定したspeed属性が削除されてしまいます。
『テキスト』で属性を付与して公開を行えば反映されますが、再度編集する際の手間が多くなります。
調べてみると、タグの制限をfunctions.phpを編集することで変更できるようですが、今回はクラス属性値にオプションを埋め込むといった方法で解決することにします。
正式版の実装
動作仕様と雛形はベータ版のまま、javascript.jsを編集して使用方法を変更します。
javascript.jsの再編集
ベータ版の実装に一部修正を加えた次のコードに置き換えます。
$(".switch-btn").click(function() { const class_array = $(this).attr("class").split(" "); const option = class_array.find((v) => v.indexOf("effect-") === 0); let [_, type, speed] = option ? option.split("-") : [undefined, undefined, 500]; speed = Number(speed) ? Number(speed) : 500; $(this).hide(); if (type === "fade") { $(this).closest('.switch-wrap').children('.switch-content').fadeIn(speed); } else if (type === "slide") { $(this).closest('.switch-wrap').children('.switch-content').slideDown(speed); } else { $(this).closest('.switch-wrap').children('.switch-content').show(speed); } });
type, speedの取得方法を変更しています。
前回は属性で指定していましたが、今回はeffect-[type]-[speed]
という形式のclass属性値を追加することで反映するようにしました。指定されない場合のアニメーションは500msです。
オプション例としては以下のようになります。
<!-- フェード, 1000msの場合 -->
<a class="btn switch-btn effect-fade-1000">ボタン</a>
使用方法
ベータ版と同様でテンプレートを挿入するだけで動作します。
また、表示方法/時間を指定したい場合は.switch-btn
と同じところにeffect-[type]-[speed]
(type: [“normal”, “fade”, “slide”], speed: [ms])の形式で属性値を記述します。
今回の機能追加でCocoonの利便さがよく分かった気がします。また、オプションの記述方法は応用が利きそうなので以降のアニメーション追加でも参考にしていこうと思います。
コメント