TOPICS
トピックス
javascriptをメディアクエリで切り替える為のjs
レスポンシブデザインのウェブサイトを作成する場合、CSSはメディアクエリで制御出来ますが、
どうしようって悩むのがjavascriptで制御している箇所の切り替えです。
例えば、グローバルメニューのサブメニューを実装する場合、スマホとタブレットでの表示は親メニューの端にあるプラスボタンをタッチするとサブメニューが表示し、マイナスボタンに変化。サブメニューオープン中にマイナスボタンをタッチするとサブメニューが閉じる。
その様に見た目だけではなくjavascriptを用いて、機能そのものをスマホ/タブレットとPCで切り替えたい事がほとんどではないでしょうか?
そんなときに便利なのが、jsファイルをメディアクエリごとに切り替える書き方になります。
この書き方を使えば、見た目のレスポンシブは出来るのに……javascriptはどうしたらいいのって場合に、完璧なレスポンシブを実現させる事が可能になります。
コードの説明
コードの説明を具体的にしていきます。
このコードは大きく2つの分岐で動きます。
一つは、window.matchMedia('(max-width:767px)').matchesや window.matchMedia('(min-width:960px)').matchesでメディアクエリによるmax-widthの値での変更ともう一つは、ua.indexOf('iPhone') > 0 || ua.indexOf('Android') > 0 && ua.indexOf('Mobile') > 0 でUA(ユーザーエージェント)ごとのデバイスによる分岐になります。
この二つの分岐が存在している理由は、PCで見た場合に単純に画面幅を小さくする事での動作と、
実機のデバイスで見た際にmax-width / min-widthに依存する事無く分岐する事が必要になってくるからです。
それともう一つの理由として、AppleなどのRetinaディスプレイやAndroidの高解像度端末は、解像度が高く横幅のピクセル数だけでは分岐することが難しいため、UA(ユーザーエージェント)の分岐が確実である為です。
以上の2点の理由により、全体ではmax-width / min-widthの分岐があり、その中のPC表示(min-width:960px)の中にUA(ユーザーエージェント)ごとにスマートフォンとタブレットさらにPCとの分岐があるという構造になっています。
例として、以下に実際に使用したコードを掲載しておきます。
実際の使用例
// JavaScript Document
$(window).on('load resize', function() {
$('#global-nav .global-nav.parent .arrow').off();
$('#global-nav .global-nav.parent').off();
$('#footer-sitemap .footer-sitemap li.parent .arrow').off();
if (window.matchMedia('(max-width:767px)').matches) {
// SPの処理
$('#global-nav .global-nav.parent .arrow').on('click', function(){
$(this).parent().next('.child').toggleClass('open').slideToggle(300);
$(this).toggleClass('open');
if ($(this).next('.child').hasClass('open')) {
//open表示中の場合
$(this).next('.child').css('display', '');
} else {
//open非表示の場合
}
});
$('#footer-sitemap .footer-sitemap li.parent .arrow').on('click', function(){
$(this).parent().next('.child').toggleClass('open').slideToggle(300);
$(this).toggleClass('open');
if ($(this).next('.child').hasClass('open')) {
//open表示中の場合
$(this).next('.child').css('display', '');
} else {
//open非表示の場合
}
});
} else if (window.matchMedia('(max-width:959px)').matches) {
// TABの処理
$('#global-nav .global-nav.parent .arrow').on('click', function(){
$(this).parent().next('.child').toggleClass('open').slideToggle(300);
$(this).toggleClass('open');
if ($(this).next('.child').hasClass('open')) {
//open表示中の場合
$(this).next('.child').css('display', '');
} else {
//open非表示の場合
}
});
if ($('.toggle-wrap').hasClass("open")) {
//open表示中の場合
$(".global-nav").removeClass('open');
} else {
//open非表示の場合
$("body").removeClass('fixed');
}
$('#footer-sitemap .footer-sitemap li.parent .arrow').on('click', function(){
$(this).parent().next('.child').toggleClass('open').slideToggle(300);
$(this).toggleClass('open');
if ($(this).next('.child').hasClass('open')) {
//open表示中の場合
$(this).next('.child').css('display', '');
} else {
//open非表示の場合
}
});
} else if (window.matchMedia('(min-width:960px)').matches) {
// PCの処理
var ua = navigator.userAgent;
if (ua.indexOf('iPhone') > 0 || ua.indexOf('Android') > 0 && ua.indexOf('Mobile') > 0) {
// スマートフォン用コード
$('#global-nav .global-nav.parent .arrow').on('click', function(){
$(this).parent().next('.child').toggleClass('open').slideToggle(300);
$(this).toggleClass('open');
if ($(this).next('.child').hasClass('open')) {
//open表示中の場合
$(this).next('.child').css('display', '');
} else {
//open非表示の場合
}
});
$('#footer-sitemap .footer-sitemap li.parent .arrow').on('click', function(){
$(this).parent().next('.child').toggleClass('open').slideToggle(300);
$(this).toggleClass('open');
if ($(this).next('.child').hasClass('open')) {
//open表示中の場合
$(this).next('.child').css('display', '');
} else {
//open非表示の場合
}
});
} else if (ua.indexOf('iPad') > 0 || ua.indexOf('Android') > 0) {
// タブレット用コード
$('#global-nav .global-nav.parent .arrow').on('click', function(){
$(this).parent().next('.child').toggleClass('open').slideToggle(300);
$(this).toggleClass('open');
if ($(this).next('.child').hasClass('open')) {
//open表示中の場合
$(this).next('.child').css('display', '');
} else {
//open非表示の場合
}
});
if ($('.toggle-wrap').hasClass("open")) {
//open表示中の場合
$(".global-nav").removeClass('open');
} else {
//open非表示の場合
$("body").removeClass('fixed');
}
$('.footer-sitemap li.main-navi.parent .arrow').on('click', function(){
$(this).parent().next('.child').toggleClass('open').slideToggle(300);
$(this).toggleClass('open');
if ($(this).next('.child').hasClass('open')) {
//open表示中の場合
$(this).next('.child').css('display', '');
} else {
//open非表示の場合
}
});
} else {
// PC用コード
$('#global-nav .global-nav.parent .arrow').removeClass('open');
$('#global-nav .global-nav.parent .child').css('display', 'none');
$('#global-nav .global-nav.parent').hover(function(){
$("ul:not(:animated)", this).slideDown("fast");
}, function(){
$(".child",this).slideUp("fast");
});
if ($('.toggle-wrap').hasClass("open")) {
//open表示中の場合
$('body').removeClass('fixed').css('top',0 + 'px');
$('#header-right').removeClass('open').css('display', 'none');
$('.toggle-wrap').removeClass('open');
} else {
//open非表示の場合
$("body").removeClass('fixed');
}
}
}
});