##スマフォwebページのスライドメニュー
アプリでは当たり前のように実装されているスライドメニューですが、webページではなかなか使い心地のよいスライドメニューが実装されているのは見かけません。
スマートフォンのブラウザではjavascriptでのアニメーションはどうしてもガタガタになってしまうし、ちらつきやスクロール制御のめんどくささからもうwebページでネイティブアプリ並のスライドメニューを実装するなんて無理と思っていました。
Facebookのwebページですらボタンの反応は悪いしアニメーションも動かないし最悪です。
##一方Google先生はパーフェクトなスライドメニューを実装していた
さすがGoogle先生! 俺達に出来ないことを(
Googleのスライドメニューは以下の点でパーフェクトです。
- スライドのアニメーションがとても滑らか・ちらつかない
- ボタンの反応にストレスを感じない
- メインコンテンツ部分のどこをさわってもメニューが閉じる
- 横スクロール対策がしっかりされている
- メニューだけスクロールできる
今回はこれらがどのように実装されているのか調査しながら、jQueryのプラグインとしてスライドメニューを実装しました。
具体的なソースはあまり載せていないので、この記事の最後に貼ってあるサンプルページとgithubを見てみてください。
##アニメーションについて
GoogleといえばFlash使わずjavascriptでなんでもやっちゃうイメージが強かったので、当然スライドのアニメーションもjavascriptを使っていると思ってソースを眺めていると、CSSにこんな記述がありました。
-webkit-transform: translateX(0);
-webkit-transition: .2s -webkit-transform ease-in-out;
CSS3のアニメーション...だと...!
参考 CSS3 - transform
スマートフォンではjavascriptではクラスの切り替えのみを行い、アニメーションはCSSに任せるのが定石のようですねー。
また、GoogleはtranslateX
を使っていますが、よくある実装としてはtranslate3d
を使いGPUアクセラレーターを有効にすることでにぬるぬる描画を実現していることが多いです。
あとソースを読んでいて気づいた細かいテクニックとしては
####実際に動かすのはコンテンツ部分
メニューはz-indexに負の値をもって奥に隠れているだけです。
横スクロール対策にもなっている
####目立たない要素はアニメーション時はhiddenにする
アニメーションを軽くするための努力
####はじっこのちらつきは背景色でカバーする
実装してみてわかってのですが、メニュークローズ時にbodyの色がちらつきます。
Googleではメニューとちらつく部分の背景色を同じにすることで対策しているようです。
##イベントについて
Facebookのスライドメニューの反応が悪いように感じるのは、おそらくonclick
でアニメーションを発火しているからです。
スマートフォンではonclick
の発生が遅いので、スマフォ特有のontouchstart
やontouchend
を使うことでストレスなく操作できます。
メニューオープンはメニューボタンのontouchend、クローズはコンテンツ部分のontouchstartにするのがよさそうです。
##メニューのスクロールについて
今回実装する上で一番苦労したがこれでした。
実際にさわってみるとわかりますがGoogleのスライドメニューはネイティブアプリと同じようにメニュー部分だけがスクロールでき、項目が多い場合でも対応できます。
なぜ苦労したか、結論から言うとスクロールの処理を自前で書いていたからです。
まず考えたのはメニュー部分をoverflow: scroll
などでスクロール可能にし、event.preventDefault()
でページ全体にイベント伝播しないようにする方法でしたが、結局うまくいかず。
困って再度Googleのソースを見てみるとメニューを囲っているdivに怪しい記述が...
style="-webkit-transform:translate3d(0px, 0px, 0px)"
さきほども登場したtranslate3d
ですね!
Googleのjsは当然 圧縮難読化されているので実際に確認してはいないのですが、どうやらメニュー部分のontouchmove
を拾って、styleにy軸方向の値を設定したtranslate3d
を連続的に書き込むことでスライドを実装しているようです。
実際この実装方法でうまくいきました。
今回作成したプログラムのソース & サンプルページ
今回作ったものを載せておきます
サンプルページ
※iPhone5でのみ動作確認してあります
※PCでは動きません(ontouch系が使えないので)
githubにもおいてあります
github - jSlideMenu
まとめ
・javascriptでなくCSS3のアニメーションを使おう
・ちらつくならtranslate3dを使おう
・ontouch系を使おう
最後に
CSS3すげぇ
角丸くできるだけかと思ってました。ごめんなさい。
Googleすげぇ
とても参考になりました。