質問: ### 前提・実現したいこと グローバルメニューを作成しています。 【PC】768px~ → 横並びメニュー → メニューをホバーすると子メニューがスライドダウンする → スマホ時のクリックイベントを解除したい 【スマホ】768px以下 → ハンバーガーメニュー → ハンバーガーメニューをクリックしてメインメニューを表示する → メインメニューの中にある子メニューをクリックしてスライドダウンで表示させたい ※この部分をPCサイズ表示ではホバーにしたいです。 いろいろ参考にしながら3回作ってみたのですが、 それぞれどこかしらに問題があるようで、挙動がおかしいです。 どこが悪いのか、ご教示いただけないでしょうか。 一応、1についてはローカルで作成したところうまく動いていたのですが、 Codepenやお客様のデモ環境にアップロードすると後述の通り、 「スマホサイズにした時に、オンマウスすると子メニューが開いてしまう」 といった現象が発生してしまいます。 以下、デモになります。 基本的にはクロームのデベロッパーツールを使ってブラウザ動かしながら作業しています。 1 → PCサイズの時にはJQueryでホバーアクションつけています。 問題点1 PCサイズで表示した際に、オンマウスでメニュー表示はされますが、トリガーとなっているメニューをクリックしても子メニューがスライドアップ、スライドダウンが発生してしまいます。 問題点2 スマホサイズにした時に、オンマウスすると子メニューが開いてしまいます。 2 →1をもっとスマートにしたい、JQueryを簡単に書きたい 問題点1 PCサイズで表示した際に、メニュー2の子メニューが開きっぱなしになってしまっています。 問題点2 スマホサイズで表示した際に、オンマウスでスライドダウンしてしまいます。 また、クリックアクションが動きません。 3 →PCサイズの時にはCSSでホバーアクションつける記述になっています。 問題点1 スマホからPCサイズにリサイズするとホバーアクションが解除されてしまっています。(サンプルデモメニューの1) 問題点2 スマホサイズにした時に子メニューが開きっぱなしになってしまいます。 またこれを解決しようとして.hide()やCSSでdisplay:noneを付けると今度はスライドしなかったり いろいろと問題が発生します。 1週間くらい考えこんでおりまして・・・どうか助けていただけないでしょうか よろしくお願いします。
回答: だいぶ混乱しているコードなので、もういっそPC用のメニューとスマホ用のメニューを別に作って、メディアクエリで不要な方を表示しないようにしてはいかがですか? ### コメントを受けて追記 要素を二つに分ける、というご提案はお気に召さなかったようなので、別のご提案をいたします。3番目の方針をベースにします。 1. まず、前提として「メニューの開閉はすべてCSSで表現する」ことに統一してください。 JavaScript と CSS が重複していることが混乱のもとです。jQueryのアニメーションはすべて削除しましょう。 2. 次に、全ての状態を整理してください。そしてこれを全てCSSで反映できるようにクラスをトグルするスクリプトを書きます。 ・PCサイズかスマホサイズか ・オープンかクローズか ・ホバーか非ホバーか 3. 最後に、CSSで全ての状態のスタイルを表現します。 以上、ご不明の点がありましたら、コメント欄にてご連絡ください。 ### コメントを受けて追記2 これは例ですが、 ``` $(function() { $(".gnavi14MenuItem._trigger, .gnavi14ChildMenuDeco").on("click", function() { $(".gnavi14ChildMenu", this).toggleClass('open'); }) }); ``` とすれば、 たとえば、SPでオープンになっていてホバーしている状態は、 ``` @media screen and (max-width: 768px) { .gnavi14MenuItem._trigger:hover .gnavi14ChildMenu.open{ } } ``` でスタイルをつけられますよね? 状態が2*2*2=8通りなので、全部列挙したとしても8パターンで済みます。 実際には、SPの時にはホバーについて書かなくてもいいですし、PCの時にはオープンの状態について書かなくてもいいので、もっとパターンが減るはずです。