最近は脱jQueryに向けて頑張っている管理人です。そこで脱jQuery第1弾、ドロワーメニューをjQueryなしで実装していこうと思います。

とりあえず成果物を見る

以下のものが今回作ったドロワーメニューです。かなり簡単に作ってはいますが、ちゃんとしたドロワーメニューになっていると思います。

See the Pen XvzLLx by takblog (@blanks-site) on CodePen.

javascriptの箇所を見てもらって分かるようにそこまで、複雑なjsにはなっていないと思います。

このドロワーメニューには以下のような特長があります。

  1. jQueryなし(ここはとりあえず。)
  2. メニューオープン時に、コンテンツエリアはスクロールされない。(これが意外に実装されていないのをよく見る気がします。)
  3. ナビのボリュームが多くなっても、ちゃんとスクロールされる。(最初の頃はこれが上手くいかなくて悩みました)

IE11に適用させる場合は、以下のスクリプトを読み込んで使用してください。

https://www.promisejs.org/polyfills/promise-7.0.4.min.js

このjsはpromiseを使用しているのですが、IE11ではpromiseが動きません。なので、IE11にも適用させたい場合は、上記のスクリプトは必須になります。

2019/9/4 修正

promiseを使わずにコールバック関数で書き直しましたので、上記のスクリプトを読み込まなくてもIE11で動きます。

ただconstなどを使用しているので、トランスパイルをする必要はあります。
私は以下のツールでトランスパイルしています。

使用しているコンパイルツール「Prepros」使用しているコンパイルツール「Prepros」

jsの説明

jsで分からない箇所がある人はここを読んでください。
コードの内容は上部のcodepenと同じものです。

コードをポップアップで見る

1〜6行目

使用する要素や、使用するクラス名を変数に入れています。
wrapperに関しては、bodyタグでもいいのですが、bodyタグでやるとsafariで動かないことが何度かあったので、私は全体を囲むwrapperを使用するようにしています。
navopenはドロワーメニューが開いているかどうかのbool値として使用しています。

9行目~ : navToggle関数

この関数はmenubtnをクリックしたときに発火する関数です。
navopenがtrueのときは、navClose関数
navopenがfalseのときは、navOpen関数
が動きます。

17行目~ : navOpen関数

ドロワーメニューをオープンする際には、wrapperに対してopenClassのクラスをつけて、スクロールしてる分だけの top: -〇〇px;をstyleつけます。
openClassをwrapperにつけると、position:fixed;が適用させるのですが、top: -〇〇px;をつけないと、ページのトップまで戻ってしまいます。それを防ぐためにtop: -〇〇px;をつけています。
そもそもposition:fixed;をつける理由は、特長(2)を実装するためです。
javascriptでスクロール禁止にする方法もあるのですが、動かない場合があったり、特長(3)を実装するのが困難になったりすることがあるので、この方法に落ち着いています。

26行目~ : navClose関数

こちらはpromiseを使って、非同期で処理を進めています。
まずメニューオープン時にwrapperにつけたtop: -〇〇px;をの -〇〇pxを取得して、sliceで〇〇の数値の箇所だけを scrolltop に入れています。
wrapperについている top: -〇〇px; を削除して、openClassのクラスも削除しています。
この処理が終わった後に、〇〇分だけスクロールさせています。
wrapperにopenClassのクラスがあるときにスクロールさせても、position:fixed;の状態なのでスクロールできないので、確実にwrapperのopenClassを削除した後に、スクロールさせています。

42行目~ : 関数の実行

memubtn要素が確認できたときだけ、関数を実行します。

html,scssの説明

ここでは今回のドロワーメニューで必要な箇所のみ説明します。

htmlコードをポップアップで見る
scssコードをポップアップで見る

scss 15~18行目

jsの説明でも書いた通り、メニューオープン時にwrapper要素はposition:fixed;にする必要があります。そのための記述です。

scss 38~40行目

スマホでスクロールしたときにヌルヌル動くためのstyleです。
またメニューのボリュームが多くなって、画面内に収まりきれないときにはスクロールできるように、overflow-y:auto;を記述しています。

html 7行目

ドロワーメニューの要素内に1つかませるために、.nav-inner要素を入れています。overflow-y:auto;でスクロールさせるときがあるのと、overflow-scrolling: touch;が正常に動かない場合があるので、その時には1つinner要素があると正常に動くので、最初からinner要素を入れています。