jQuery 横並びリストのリストアイテムをアニメーション表示

例えばシェアボタン、あるいはフォローのボタンと言うのは、もちろん予めその内容を表示していても良いのですが必ずしも表示していないといけないというわけではなく、何かしらのギミックが欲しい部分でもあります。

例えばボタンが表示されていない場合は閉じておき、スクロールなどによって表示領域に入ったら開くと言う手法も考えられます。またシェアやフォローしたい人はボタンから、そうでない人はただのページ内のデザインと言うのも良いのかも知れません。ここらのアイデアは色々と考えられますが、まずそのリストアイテムをアニメーションさせる所を書いてみたいと思います。

ただし、色々とやっている割には細かな設定をしていないので、リストアイテムの配置はabsolute、つまり座標に対して配置しています。本来はrelativeとして相対的にやるのが望ましいと思います。そうすれば、リストアイテムが増えた場合でも自動的に画面端に来れば改行しますし、display: flexなどを利用していた場合、うまくそのルールに従って配置されたり、サイズが自動で揃ったりすると思うのです。

なぜabsoluteでの設計になったかと言いますと、ulをボタンにしてしまったからです(笑)
別のボタンを発火用に用意しておけば、relativeでもできたように思うんですけれども、あっ…と思った時には時既に遅しでした(笑)

まぁなんにせよ、理屈がわかれば応用もできるというもの、ひとまずはcodepenのサンプルでも見てその動作を把握してみてください。

See the Pen Click button to open list by Hidekichi (@Hidekichi) on CodePen.

今回のは画面内で収まるので、上記のサンプルで理解してもらえると思います。

動作の仕組みと仕様

まず、色ですが、ul class=”red”と指定しています。

背景を赤(#f00)にして、シェアアイコンとfollow部分は白(#fff)にして、カウントの部分だけやや暗めの赤にしています。もし仮に、blackと言うclassを作るのであれば、

こんな感じでしょうか。色の部分は分離したので、比較的簡単に色を決定できます。

jQueryに関しては、元々のボタン(ul)部分をクリックすると.toggleClassでonclickと言うクラスを追加しています。toggleClassにしているので、再度クリックすればonclickは取り除かれます。

onclickがついたり外れたりしているのをhasClassで監視して、もし、ulがonclickを持っていた場合は、閉じている所から開いたと言うことになるので、子要素であるliを表示する処理になります。この時に、follow部分を表示するようにしています。

これはcssで予め左側に500px(-500pxとして)に表示させておいて、もしul.onclickになった時に transform: translate3d(530px, -50%, 0);とすれば左から30pxの所に持ってこれるという感じになっています。

translate3d()はそのパラメーターにx,y,zと座標を持っており、上記例なら、x方向に530px、y方向に-50%、z方向は0分自身を動かすと言う意味合いとなります。y方向に-50%とあるのは、top:50%;としており、そこから自身を-50%動かすことで縦中心に揃えるための方法です。

これは案外使うのでもう少し詳しく書くと、top:50%で動かした要素は、その要素のoffset、つまりその要素が四角い箱だとして、その要素の左上コーナーが50%の位置に移動します。と言うことは、四角い箱の上辺はきちんと50%の位置に来ているものの、要素の高さがあるため、実際の中心は下にずれます。完全に中心に揃えるためには、その要素の半分をマイナスする必要があるわけです。

例をあげてみましょう。

縦横50pxの箱があったとします。それを内包する縦横300pxの箱があった時、その内包している方の縦中心は300/2で150pxの位置というのはすぐにわかります。しかし、中に入っている箱は50pxの高さを持っているので、内包する箱の半分の位置、150pxの所でY座標で言うと0になりそこから下に50px分の高さをもって位置するわけです。
正しく中心に揃えるためには、50pxの高さの半分の25pxの座標が、内包している箱の150pxの位置に来れば良いことになります。
つまりは、外の箱300px/2=150px、中の箱50px/2= 25px、150px-25px = 125px(Y座標)が中の箱の上辺にくれば中心ということになります。

これをcssで当てはめると、top: 50%は内包している箱の半分の位置、つまり150px。
50pxの箱の半分は、transform: translate3d(0,-50%,0)の位置、つまり自身を半分マイナスしているわけです。

これらの操作で、中央にしたい箱(ブロック):Bは、それを内包するブロック:Aのtop:50%、中央にしたい箱自身を-50%することで必ず内包する箱の縦中央に位置することになります。仮に、Aの高さを変更したとしても必ずBはAの縦中央に揃います。もちろんBの高さを変えたとしても揃います。

一番最初のシェアボタン他は、このようにして縦中央に位置しています。

ulがonclickと言うクラスを持った時、子要素であるliがアニメーションする部分はjQueryでやっています。

ここでは、まず.testブロック内にあるulの中のliを探し、まずcssで透明にします(opacity:0)。そして子要素の位置を左側から120pxの位置にしています。120pxはシェアボタンが開いた時の幅に+20pxしているだけです。
そしてeachによってli全部に対してアニメーションする処理をしています。

.each(function(i,value){…})のiは子要素のindexです。0から始まります。このことから、一番最初の要素liはdelay(i*80)とあっても、iが0ですから、何も遅延はしません。しかし次の2つ目の要素liは(indexは1)、1*80となるのでdelayで80ミリ秒待ってから表示されます。3つ目の要素は2*80なので160ミリ秒後に動作するという感じです。

left: i*80 + 120の部分も同様に、indexが0の場合は、left: 120px、indexが1の時は、80+120で200pxの位置というように位置が決められていきます。最初に.css()部分でopacityを0(透明)にしているので、目的の位置に付く前は透明で徐々に表示されて目的の位置に到達するという感じになります。

今度は、ulでシェアボタンの部分が閉じた時の処理ですが、followのテキスト部分は、元々左に500px移動させているのでonclickのクラスがなくなれば、元の-500pxの位置に戻ります。これらがアニメーションしているように見えるのは、transition: .3s easeと、いうcssが仕込んであるためです。

子要素のliが左へ消えていくのは、

この部分がしています。

var childs = $(“.test ul li”).lengthでは、li要素がいくつあるのかを数えています。サンプルでは子要素は4つありますがindexは0から始まっているので、.lengthで4個の要素が取得されますが実際は3が取得されます。
jQueryの1.8ぐらいからeq()の値がマイナスの場合最後の要素から適用されるようになりました。そのために、3に対して-1をかけることでマイナスの値を取得して、最後の要素から処理を始めるようにしています。

ここで一番注意が必要な場所が、j++です。jは+1ずつ増えていく(インクリメントされる)わけですが、初期値は-3になるので、-3+1で2つ目のループの時は-2が出てきます。もし仮にj–とデクリメントした場合は、-3-1で-4と要素liが増えてしまうことになりループに問題が発生します。
本来はサンプルであればliの要素は4つ(indexで3)しかないはずなのに、5つ、6つと増えていけば該当する要素がないのにループは進んでいく、つまり無限ループになるわけです。これはスクリプトが止まってしまうということですね。これは最大の注意が必要です。

次に、$(“.test ul li”).eq(j).delay(80).animate({の部分。jは-1を書けてあるのでサンプルを例で言うと最初は-3が入ります。eqの中身がマイナスだと要素の最後から実行されるというのは先に書いたとおりです。

更にその中身のleft: j* 80,は、-3 * 80で-240px最後のliが移動して、2回目のループでは、-2 * 80で-160px、3回目では -1 * 80 で-80pxと減っていきます。最終的にはopacity:0が効くので、とりあえずその効く間に左に動いていればそれっぽい動作になるという寸法です。

縦の動きは、以下のサンプル

スポンサーリンク

シェアする

フォローする