レスポンシブデザインで、PCサイズではメニューを表示し、スマホサイズではアイコン化したい場合
例えばメニューのIDが「menu」で、アイコンのIDが「icon」だった場合、CSSは
#menu {display:block;}
#icon {display:none;}
@media only screen and (max-width:640px) {
#menu {display:none;}
#icon {display:block;}
}
などととします。
そしてアイコンをクリックしたときにメニューを表示するために以下のスクリプトを組み込みます。
(JQueryを使用する前提です)
$(function(){
$("#icon").click(function(){
$("#menu").toggle();
});
});
これでとりあえずは実現できたのですが、ちょっと問題が発生します。
アイコンをクリックした後にウィンドウサイズを変更すると、ウィンドウサイズに連動した表示/非表示が機能しなくなるのです。
これはjavascriptで変更したcssはタグに直接記述したのと同じなので元々のcssより優先されてしまうからです。
問題を解消するためはウィンドウサイズ変更時にjavascriptで追加・変更したcssを削除する必要があります。
$(window).resize(function() {
$("#menu").css('display','');
});
しかし、これではリサイズ中(ドラッグ中)、処理が非常に短い周期で何回も呼ばれてしまいます。
これでも問題無い場合が多いですが、リサイズ終了を待ってから処理を行った方がスマートです。
実際にはリサイズ終了を認識することはできませんので、リサイズイベントから一定時間後(例では200ミリ秒後)に処理を実行するようにし、リサイズイベントのたびにタイマーをリセットすることで処理を1回で済ませるようにします。
var timer = false;
$(window).resize(function() {
if (timer !== false) {
clearTimeout(timer);
}
timer = setTimeout(function() {
$("#menu").css('display','');
}, 200);
});
もっと良い方法があるとは思いますが、とりあえずこれで目的は達せられました。
*********** 追記 1 ***********
スマホでタッチによるスクロールを行うと出ていたメニューが消えてしまうことがわかりました。
つまりリサイズしなくてもスクロールしただけでresizeイベントが発行されてしまうようです。
要修正です。
*********** 追記 2 ***********
推測ですが、スマホでスクロールするとアドレスバーが消えたりスクロールバーが現れたりする関係で一時的に(微妙に)表示領域が変わり、resizeイベントが発生してしまうのではないかと考えました。
そこで以下のようにスクリプトを修正し、前後の画面幅を比較することにしました。
結果は良好で、今のところ狙い通りに動いています。
var timer = false;
var width = $(window).width();
$(window).resize(function() {
if (timer !== false) {
clearTimeout(timer);
}
timer = setTimeout(function() {
if (width !== $(window).width()){
$("#side").css('display','');
width = $(window).width();
}
}, 200);
});
0 件のコメント:
コメントを投稿