初めまして!
昨年12月に未経験で入社しました、フロントエンドエンジニアのきっしゃんです。
エンジニア
きっしゃん
先日、Chromeのデベロッパーツールでハンバーガーメニューの表示確認をしていると、
ハンバーガーメニューである三本線をクリックした時に本来表示されるメニューがブレイクポイントでチラ見えしている状況を発見してしまいました、、、。
イメージ的には下記のような感じです。
最終的にはJavaScriptのリサイズイベントを使用して解決させたのですが、
これはどうやって解決させようと結構悩んだこともあり、
もしかしたら同じように悩んでいる人も居るかも?と思ったため、
今回はハンバーガーメニューをクリックした際に表示されるメニューがウィンドウサイズ変更時に生じるチラつきを解消する方法について書きたいと思います。
チラつきを解消したコードの完成形
下記コードがメニューのチラつきを解消した完成形になります。
resizeイベントでウィンドウサイズの変更中はtransiton
をnone
にしているのがポイントになります。
See the Pen ハンバーガーメニューのチラつき by shota kishimoto (@shota-kishimoto) on CodePen.
ハンバーガーメニューがチラつく原因は?
そもそもハンバーガーメニューをクリックした際に表示されるはずのメニューがブレイクポイントでちらついていた原因は、ハンバーガーメニューに使用しているtransition
にあります。
画面の左右からふわっと出したり、本記事のデモのようにふわっと出現させたりするために、
皆さんもtransition
を使用しているんじゃないかなと思います。
本記事のデモでは下記のように設定していました。
.header__nav {
position: fixed;
top: 0;
left: 0;
right: 0;
opacity: 0;
padding-top: 108px;
background-color: #f97763;
height: 100%;
transition: opacity 0.3s ease-in;
}
実際に上記のtransiton
を使用しないようにした場合、
さっきはウィンドウサイズ変更中にチラついていたメニューが一切表示されないようになります。
ということは、ウィンドウサイズの変更中にはtransition
を効かないようにしてあげることで、
ハンバーガーメニューをクリックした際に表示されるメニューのチラつきが解消されることになりますね。
ハンバーガーメニューのチラつきを解消する方法
原因が判明したところで、
本題のチラつきを解消する方法について書きたいと思います。
方法は色々あるかもしれませんが、
僕自身はJavaScriptのresizeイベントを用いて解消しました。
そのコードは下記になります。
class Resize {
constructor(target) {
this.timeoutId;
this.target = document.querySelector(target);
window.addEventListener("resize", this._resize.bind(this))
}
_resize() {
this.target.classList.add("is-resize");
clearTimeout(this.timeoutId);
this.timeoutId = setTimeout(() => {
this.target.classList.remove("is-resize");
}, 500);
}
}
new Resize("html");
.is-resize .header__nav {
transition: none;
}
リサイズ中は.is-resize
をhtmlタグに付与することでその間はtransitionをnoneにし、
リサイズ終了から0.5秒後に.is-resize
を外すというシンプルなものです。
このようにすることで無事にハンバーガーメニューのチラつきを解消させることが出来ました。
上記の例ではnew Resize("html")
でhtmlタグに.is-resize
を付与するよう指定していますが、
こちらはbodyタグやクラス名など好きに変えてくださって大丈夫です。
jQueryを使っている人向け
普段jQueryを使っている方もいるかと思うので、
下記にjQueryの書き方で書いた場合のコードも記載しておきます。
jQueryを使っている方はぜひこちらを使ってみてください。
let timeoutId;
$(function() {
$(window).resize(() => {
$("html").addClass("is-resize");
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
$("html").removeClass("is-resize");
}, 500);
})
})
こちらも$("html")
は好きに変更して使用してください。
最後に
ハンバーガーメニューはサイト制作する際によく用いられるため、
同じような問題に出くわしている方も居るんじゃないかなと思います。
その場合には、ぜひ一瞬transitionを無くすことでチラつきを解決してみてください。
エンジニア大募集中!!
ロジカルスタジオでは、現在エンジニア大募集中です!
採用サイトをリニューアルしたので、ぜひ下記バナーから覗いてみてくださいね!