【JavaScript】ドロワーメニューの作り方
ブログのスマホレイアウト時に使いたかったので作成した。
サンプル
前提
下記の関数を定義済みの想定とする。
- 【JavaScript】DOMを操作する時によく使う関数の一覧( プロトタイプ拡張 )
- 【JavaScript】要素をホバーした時のイベントを登録する関数( プロトタイプ拡張 )
- 【JavaScript】ウィンドウをリサイズした時のイベントを登録する関数( プロトタイプ拡張 )
手順
ドロワーメニューのイベントを登録するオブジェクトを定義する
ドロワーメニューのイベントを登録するため、下記のオブジェクトを定義する。
function DrawerEventRegisterer() {
let _isOpening = false;
function _register() {
const BUTTON = document.querySelector( '#drawer .button' );
if ( BUTTON === null ) return;
const CLOSE_AREA = document.querySelector( '#drawer .close-area' );
if ( CLOSE_AREA === null ) return;
const MENU = document.getElementById( 'drawer-menu' );
if ( MENU === null ) return;
const ACTIVE_CLASS_NAME = 'active';
const onOpen = function() {
_isOpening = true;
BUTTON .addClass( ACTIVE_CLASS_NAME );
CLOSE_AREA .addClass( ACTIVE_CLASS_NAME );
MENU .addClass( ACTIVE_CLASS_NAME );
};
const onClose = function() {
_isOpening = false;
BUTTON .removeClass( ACTIVE_CLASS_NAME );
CLOSE_AREA .removeClass( ACTIVE_CLASS_NAME );
MENU .removeClass( ACTIVE_CLASS_NAME );
};
_registerPushedEvents( BUTTON, CLOSE_AREA, onOpen, onClose );
_registerResizedEvent( BUTTON, onClose );
}
function _registerPushedEvents( button, closeArea, onOpen, onClose ) {
const onPushedButton = function() { if ( !_isOpening ) onOpen(); };
const onPushedCloseArea = function() { if ( _isOpening ) onClose(); };
button .registerOnPushed( onPushedButton );
closeArea .registerOnPushed( onPushedCloseArea );
}
function _registerResizedEvent( button, onCompleted ) {
const onResized = function() {
if ( !_isOpening ) return;
const DISPLAY = button.getStylesheetValue( 'display' );
if ( DISPLAY !== 'none' ) return;
onCompleted();
};
window.registerOnResized( onResized );
}
return {
register: _register,
};
};
各パーツを表示するために必要なHTMLを記述する
「ボタン」、「閉じるエリア( メニューを閉じるための領域 )」、「メニュー」を表示するため、下記のHTMLを適当な箇所( body
要素の直下など )に記述する。
<div id="drawer">
<div class="button">
<div class="line"></div>
<div class="line"></div>
<div class="line"></div>
</div>
<div class="close-area"></div>
</div>
<div id="drawer-menu">
</div>
DOMContentLoadedイベントでオブジェクトを生成し、関数を呼ぶ
DrawerEventRegisterer
オブジェクトを生成し、register
関数を呼ぶ処理をdocument
オブジェクトのDOMContentLoaded
イベントに登録する。
document.addEventListener( 'DOMContentLoaded', function() {
const DRAWER_EVENT_REGISTERER = new DrawerEventRegisterer;
DRAWER_EVENT_REGISTERER.register();
} );
メニューで表示する要素を追加する
先ほど記述したHTMLの<div id="drawer-menu"></div>
内にメニューで表示する要素を追加する。
<div id="drawer">
<div class="button">
<div class="line"></div>
<div class="line"></div>
<div class="line"></div>
</div>
<div class="close-area"></div>
</div>
<div id="drawer-menu">
ここにメニュー内で表示する要素を追加
</div>
メニューに動きを付ける
「メニュー」に動きを付けるため、下記のCSSを記述する。
#drawer-menu {
position: fixed;
left: -100%;
transition: left .3s ease-in;
}
#drawer-menu.active {
left: 0;
transition: left .5s cubic-bezier(0,.8,.6,1);
}
これでボタンを押した際に左側からメニューが出てくるようになる。
CSSで見た目を整える
後はHTMLの各要素に付いているIDとクラスを用いて、CSSで見た目を整える。