[jQuery]PC/SP(レスポンシブ)で確実に動作を切り替える方法

コードの見栄えは悪いけど地味に使えるぞこれは。

やりたいこと

PCだとマウスオーバー時、SPだとタップ時にjsが動作するようにする。

レスポンシブで組むため、デバイス毎ではなくブラウザ幅で変化することになる。

よく思いつく感じなのはこう。

$(function(){
    $(window).on('load resize', function(){
        if(window.matchMedia('(max-width:767.98px)').matches){
            $('header').addClass('sp');
        }else{
            $('header').removeClass('sp');
        }
    })
    $('header ul > li.sub > a').mouseover(function(){
        if(!$('header').hasClass('sp')){
            //PCだったらマウスオーバーで動く
        }
    }).click(function(){
        if($('header').hasClass('sp')){
            //SPだったらクリックで動く
        }
    })
})

思いつくというか作例があるというか。読み込み時とかに幅を取得して.spを付与するアレでPC/SPのifでやっていく。これでも間違いじゃないんだけど、人力最速で読み込み直後にクリックすると.addClass()を追い越して処理されて動作がバグる事がある。読み込みが遅いとかなら尚更。追い越された処理は止まってしまう。更に厄介なのが、このバグは再読み込み時にも残る。キャッシュをクリアしないといけない。

要するに、こんな感じの幅判定からの条件分岐はよろしくないから変えましょうという話。

解決策

$(function(){
    $('header ul > li.sub > a').mouseover(function(){
        if(!window.matchMedia('(max-width:767.98px)').matches){
            //PCだったらマウスオーバーで動く
        }
    }).click(function(){
        if(window.matchMedia('(max-width:767.98px)').matches){
            //SPだったらクリックで動く
        }
    })
})

こうすればアクション時の処理を行う前に必ず判定が入るから処理が前後しなくなる。

予めclassを付与してそれをトリガーにするんじゃなくて、都度幅判定をやっていく、ということ。なんか回りくどいというか、一元管理できないモヤモヤがあるんだけどこればっかりはどうしようもない。なかった。まあ、数値だけなら変数で済むけどさ。

でも。

.hasClass()が悪いんじゃなくて、使い所があるよっていう話。色々段階を踏む中に加えるのであればなんにも問題ない。.addClass()の条件に.load()が絡むと厄介だよっていうね。

ブラウザ幅取得について

幅の取得は色々あるけど、ネックになるのはcssとの兼ね合い。物によってはスクロールバーの幅とかが絡んで、微妙にずれたりする。なんかもうほんとめんどくさいから、.matchMedia()でやるのが脳みそ使わずに済んでいいと思います。

コメント

タイトルとURLをコピーしました