質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.77%

関数の実行を画面の幅によって制御したい。

解決済

回答 3

投稿

  • 評価
  • クリップ 1
  • VIEW 3,202

前提・実現したいこと

サイトをロード、リサイズしたとき、
グローバルナビについて、640px以上のときはホバーしたときに
アコーディオンがスライドするようにして、640px以下のときは
クリックしたときにスライドするようにしたい。

発生している問題・エラーメッセージ

640px以上のときはpcNavAction()という関数が実行され、
640px以下のときはspNavAction()という関数が実行されるようにしたい。

現状は
640px以上のときにサイトをロード、リサイズすると、
pcNavAction()という関数が実行され、また640px以下のときでも実行される。
spNavAction()は実行されない。

640px以下のときに、サイトをロード、リサイズすると
spNavAction()という関数は実行されず、pcNavAction()も実行されない。
640px以上になるとpcNavAction()が実行される。

変数breakPに640を代入しています。

ソースコード

$(window).on("load resize", function() {
    if ($(this).width() > breakP) {
        pcNavAction();
    } else {
        spNavAction();
    }
});

function pcNavAction() {
    $accordion.on({
        'mouseenter': function() {
            $(this).find('ul').stop().slideDown();
            $(".conf").css('border-bottom', '3px solid #006CB2');
        },
        'mouseleave': function() {
            $(this).find('ul').stop().slideUp();
            $(".conf").css('border-bottom', '');
        }
    });
};

function spNavAction() {
    $accordion.on('click', function() {
        $(this).find('ul').slideToggle();
    });
};

よろしくお願いいたします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

checkベストアンサー

0

発生している問題に対処できたかは分かりませんが
実現したいことの仕様に基づくコードを書いてみました。
これでどうでしょうか。

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <title>28198</title>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <script>
      $(function(){
        var breakP = 640;
        var $accordion = $(".accordion");
        var is_sp = null; // 追加: 今sp用表示か?

        $(window).on("load resize", function() {
          if ($(this).width() > breakP && is_sp !== false) {
            // ウィンドウサイズが640超過かつ
            // 現在の表示がsp用表示の場合(または初回)に呼び出される
            pcNavAction();
          } else if ($(this).width() <= breakP && is_sp !== true) {
            // ウィンドウサイズが640以下かつ
            // 現在の表示がpc用表示の場合(または初回)に呼び出される
            spNavAction();
          }
        });

        function pcNavAction() {
          $accordion.off('click'); // 追加: sp用ハンドラを削除
          $accordion.on({
            'mouseenter': function() {
              $(this).find('ul').stop().slideDown();
              $(".conf").css('border-bottom', '3px solid #006CB2');
            },
            'mouseleave': function() {
              $(this).find('ul').stop().slideUp();
              $(".conf").css('border-bottom', '');
            }
          });
          is_sp = false; // 追加: pc用に切り替えた
        }

        function spNavAction() {
          $accordion.off('mouseenter mouseleave'); // 追加: pc用ハンドラを削除
          $accordion.on('click', function() {
            $(this).find('ul').slideToggle();
          });
          is_sp = true; // 追加: sp用に切り替えた
        }
      });
    </script>
    <style>
      .accordion {
        background-color: #eee;
        padding: 5px;
      }

      ul {
        background-color: #ddd;
      }
    </style>
  </head>
  <body>
    <div class="accordion">
      <p>open/close</p>
      <ul>
        <li>foo</li>
        <li>bar</li>
        <li>baz</li>
      </ul>
    </div>
  </body>
</html>


違った書き方。

$(function(){
  var breakP = 640;
  var is_sp = null;

  $(".accordion").on({
    'mouseenter': function() {
      if(is_sp) return; // pc用表示でない場合は終了
      $(this).find('ul').stop().slideDown();
      $(".conf").css('border-bottom', '3px solid #006CB2');
    },
    'mouseleave': function() {
      if(is_sp) return; // pc用表示でない場合は終了
      $(this).find('ul').stop().slideUp();
      $(".conf").css('border-bottom', '');
    },
    'click': function() {
      if(!is_sp) return; // sp用表示でない場合は終了
      $(this).find('ul').slideToggle();
    }
  });

  $(window).on("load resize", function() {
    is_sp = $(this).width() <= breakP;
  });
});

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/02/25 10:34

    とても詳しく丁寧にコードをかいていただいて
    本当にありがとうございました!
    うまく動くようになり、とても助かりました!!

    キャンセル

0

JavaScriptの制御もレスポンシブにしたいよね。
matchMediaがいいよ。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/02/25 10:57

    matchMediaメソッドがあるの初めてしりました!
    今後、勉強して活用していきたいです!

    キャンセル

0

onのバインドは、一度関連づけられると意図的にoffにしないと関連づけられたままです。
なので、現行の書き方だと両方が適用された状態が生まれています。
それが不具合の原因です。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/02/25 10:59

    その通りでした。
    on.offの使い方を理解していけるよう努力したいです!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.77%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る