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

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

新規登録して質問してみよう
ただいま回答率
85.48%
CSS3

CSS(Cascading Style Sheet)の第3版です。CSS3と略されることが多いです。色やデザインを柔軟に変更することが可能になります。

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Q&A

解決済

1回答

1031閲覧

グローバルメニューを正しく動作させたい

lingwood

総合スコア40

CSS3

CSS(Cascading Style Sheet)の第3版です。CSS3と略されることが多いです。色やデザインを柔軟に変更することが可能になります。

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

0グッド

1クリップ

投稿2020/04/02 09:08

編集2020/04/03 01:07

前提・実現したいこと

グローバルメニューを作成しています。
【PC】768px~
→ 横並びメニュー
→ メニューをホバーすると子メニューがスライドダウンする
→ スマホ時のクリックイベントを解除したい

【スマホ】768px以下
→ ハンバーガーメニュー
→ ハンバーガーメニューをクリックしてメインメニューを表示する
→ メインメニューの中にある子メニューをクリックしてスライドダウンで表示させたい
※この部分をPCサイズ表示ではホバーにしたいです。

いろいろ参考にしながら3回作ってみたのですが、
それぞれどこかしらに問題があるようで、挙動がおかしいです。
どこが悪いのか、ご教示いただけないでしょうか。

一応、1についてはローカルで作成したところうまく動いていたのですが、
Codepenやお客様のデモ環境にアップロードすると後述の通り、
「スマホサイズにした時に、オンマウスすると子メニューが開いてしまう」
といった現象が発生してしまいます。

以下、デモになります。
基本的にはクロームのデベロッパーツールを使ってブラウザ動かしながら作業しています。

1 https://codepen.io/lingwood/pen/gOpyLwZ

→ PCサイズの時にはJQueryでホバーアクションつけています。

問題点1
PCサイズで表示した際に、オンマウスでメニュー表示はされますが、トリガーとなっているメニューをクリックしても子メニューがスライドアップ、スライドダウンが発生してしまいます。

問題点2
スマホサイズにした時に、オンマウスすると子メニューが開いてしまいます。

2 https://codepen.io/lingwood/pen/JjdVbwZ

→1をもっとスマートにしたい、JQueryを簡単に書きたい

問題点1
PCサイズで表示した際に、メニュー2の子メニューが開きっぱなしになってしまっています。

問題点2
スマホサイズで表示した際に、オンマウスでスライドダウンしてしまいます。
また、クリックアクションが動きません。

3 https://codepen.io/lingwood/pen/ZEGZBNJ

→PCサイズの時にはCSSでホバーアクションつける記述になっています。

問題点1
スマホからPCサイズにリサイズするとホバーアクションが解除されてしまっています。(サンプルデモメニューの1)

問題点2
スマホサイズにした時に子メニューが開きっぱなしになってしまいます。
またこれを解決しようとして.hide()やCSSでdisplay:noneを付けると今度はスライドしなかったり
いろいろと問題が発生します。

1週間くらい考えこんでおりまして・・・どうか助けていただけないでしょうか
よろしくお願いします。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

だいぶ混乱しているコードなので、もういっそPC用のメニューとスマホ用のメニューを別に作って、メディアクエリで不要な方を表示しないようにしてはいかがですか?

コメントを受けて追記

要素を二つに分ける、というご提案はお気に召さなかったようなので、別のご提案をいたします。3番目の方針をベースにします。

  1. まず、前提として「メニューの開閉はすべてCSSで表現する」ことに統一してください。

JavaScript と CSS が重複していることが混乱のもとです。jQueryのアニメーションはすべて削除しましょう。

  1. 次に、全ての状態を整理してください。そしてこれを全てCSSで反映できるようにクラスをトグルするスクリプトを書きます。

・PCサイズかスマホサイズか
・オープンかクローズか
・ホバーか非ホバーか

  1. 最後に、CSSで全ての状態のスタイルを表現します。

以上、ご不明の点がありましたら、コメント欄にてご連絡ください。

コメントを受けて追記2

これは例ですが、

js

1$(function() { 2 $(".gnavi14MenuItem._trigger, .gnavi14ChildMenuDeco").on("click", function() { 3 $(".gnavi14ChildMenu", this).toggleClass('open'); 4 }) 5});

とすれば、
たとえば、SPでオープンになっていてホバーしている状態は、

css

1@media screen and (max-width: 768px) { 2 .gnavi14MenuItem._trigger:hover .gnavi14ChildMenu.open{ 3 } 4}

でスタイルをつけられますよね?

状態が222=8通りなので、全部列挙したとしても8パターンで済みます。
実際には、SPの時にはホバーについて書かなくてもいいですし、PCの時にはオープンの状態について書かなくてもいいので、もっとパターンが減るはずです。

投稿2020/04/03 07:00

編集2020/04/03 10:22
Lhankor_Mhy

総合スコア36115

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

lingwood

2020/04/03 07:30

Lhankor_Mhy 様 ご提案ありがとうございます。 今できるうちに解決したいもので・・・気に留めてくださりありがとうございます。
Lhankor_Mhy

2020/04/03 07:34

私のご提案は採用しない、と読みましたが、合っていますか?
lingwood

2020/04/03 08:09

恐れ入ります。曖昧な回答をしてしまいすみませんでした。 お気持ちは大変うれしく思いましたが、ご提案いただいた案につきましては今抱えている問題の解決になっていないと考えました。もちろん時と場合によりますが、できればdisplay:noneなどは使わずちゃんと切り替えができるほうがサイトにとっても良いと思っています。 このようなことですみません。よろしくお願い致します。
Lhankor_Mhy

2020/04/03 08:20

あ、いえ、別に気を悪くしたとかそういうことではないんです。追記をするのに確認をしたかっただけなので。 で、追記しました。
Lhankor_Mhy

2020/04/03 08:32

あと、誤解されているかもしれませんが、PC用とスマホ用のナビゲーション要素を分ける手法は、wordpressのテーマなどでも採用してることがあるやり方なので、別に手抜きというわけではないと思います。
lingwood

2020/04/03 08:45

ありがとうございます。追記拝見させていただきました。 まずは整理して少しずつやってみます。 それと、navi要素を別々に分けるのは存じており、また、場合によって小生もやったことはあります。 ただ今回、できればメニュー修正等の際に漏れ抜け間違いをなくすという意味でも1か所でやってしまいたいという希望があります。 また、ネット上を探しても意外とこの部分の記述が少なかったり、複雑なことに取り組むことで今後の勉強にもなると思い、質問させていただいた次第です。 気に留めてくださって本当にうれしく思います。
Lhankor_Mhy

2020/04/03 08:48

勉強ということであれば、具体的なコードをご提示することはやめた方がよさそうですね。 ご健闘をお祈りします。
lingwood

2020/04/03 08:56

ありがとうございます。 3つめが今の一番新しいところでして、納品差し迫っているものになります。 お分かりになるようでしたらご指摘いただけたらと思いますが、お願いできますでしょうか。
lingwood

2020/04/03 09:28

Lhankor_Mhyさん 今日はとても貴重な時間をくださいまして、ありがとうございました。 会社が都内なもので今日はもう帰れと言われてしまいました。 何とか自分なりにも改修急いでいるのですが、時下このような世情のため月曜日に持ち越すことにいたします。週明けまた取り組みたいと思います。もう少しだけお時間いただければと思います。 よろしくお願い致します。
lingwood

2020/04/06 01:56

おはようございます。 先週はありがとうございました。 思考の整理に導いていただき大変助かります。 上記の例ですが、 メニューが2つある場合は、.gnavi14MenuItem._trigger1、.gnavi14MenuItem._trigger2のようにしなければいけないのでしょうか? それをデモの2に使っているul:not(:animated)を使うことでできたりしないのでしょうか? 何度もすみませんが、よろしくお願い致します。
Lhankor_Mhy

2020/04/06 08:44

> メニューが2つある場合は、.gnavi14MenuItem._trigger1、.gnavi14MenuItem._trigger2のようにしなければいけないのでしょうか? その必要はないと思いますよ。クラスは同じ名前を複数の要素につけることができます。
lingwood

2020/04/06 09:44

Lhankor_Mhy 様 ご回答ありがとうございます! そうですか・・・クラス名を同じにするとひとつをクリックした際に、同時に開いてしまうのですが・・・どこがおかしいのでしょうか...? ただ少し進展しましたので、明日、もう一度Codepenで動かしてみたいと思っています。 お手数をおかけしてすみませんが、もしお時間ございましたらまたご指摘いただけますでしょうか。 よろしくお願い致します。
Lhankor_Mhy

2020/04/06 09:53

>どこがおかしいのでしょうか...? 当方で試したところそのようにはなりませんでしたので、問題が再現しませんでした。 問題が再現するコードをご提示いただかないと何とも。
lingwood

2020/04/07 00:49

おはようございます。 試行していただいたんですね・・・いろいろと本当にありがとうございます。 コードを一部刷新してできるだけCSSを活用する方向で作成してみました。 https://codepen.io/lingwood/pen/JjdQqPo Codepen上で何とか動かすことができました。 ただ、昨夕のクラス名重複につきましては以下のような形になってしまうということで書きました。 PC表示上のホバーアクションは問題ないのですが、スマホ時のスライドメニューが同時に開いてしまいます。 https://codepen.io/lingwood/pen/VwLoraQ すみませんが、ご指南いただけますでしょうか?
Lhankor_Mhy

2020/04/07 01:18

回答にも書きましたが、 $(".gnavi14ChildMenu", this) とすればいいと思いますよ。
lingwood

2020/04/07 02:51

Lhankor_Mhy 様 ありがとうございます!できました!! 今までネット上にあるプログラムをちょっといじる程度でやってきたので、thisについて英語の直訳でしか理解していませんでした。ちゃんと調べたところ、複数の要素からクリック要素だけを取得することもできるとのことで、考えてみればそういう捉え方も確かにできることと大変勉強になりました。 最後に2つ教えていただけませんでしょうか? まず、アコーディオンを開く際にスムーズに開くようにしたかったため、スマホ時はtoggleClassからslideTggleにしました。 ひとつめの質問ですが、 toggleClassなどでクラスを付与した場合に、CSSでうまくslideToggleのようにスムーズにメニューを開くことができませんでした。CSSでもこれを解決する方法(コード)はあるのでしょうか? もうひとつの質問ですが、 slideToggleを指定のWindowサイズで完全に切り分けて実行させたり解除する方法はあるのでしょうか? 例えば今回のコードでは、スマホ表示で子メニューを閉じた際にslideToggleが入っているためPC表示に戻した際にdisplay:none;が継承されてしまい、それをメディアクエリでmin-width:768px;の時、display:block !importantとすることで解決しています。!importantを使わないでも解決できる方法はありますでしょうか? 何度もすみませんが、ご教示いただけましたら本当にうれしく思います。 よろしくお願い致します。
Lhankor_Mhy

2020/04/07 03:27

>CSSでもこれを解決する方法(コード)はあるのでしょうか? transition でいいのではないですか? >slideToggleを指定のWindowサイズで完全に切り分けて実行させたり解除する方法はあるのでしょうか? すでに、CSSで表現するように統一するか、サイズごとに要素を用意することをお勧めいたしました。 どうしても、CSSとJavaScriptを混在させたいのであれば、丁寧に一つずつロジックで切り分けるしかないと思いますよ。たとえば、datasetに状態を持たせておいて、resizeイベントの際にすべてをチェックして不整合のある状態であれば変更する、などです。
lingwood

2020/04/07 04:34

ありがとうございます! 以前にも「slideToggle 解除」などで調べた際にめぼしいものがなく今日まであやふやに考えてきましたがとてもすっきりしました。 何とか納品に間に合いそうです。いろいろとご教示いただきありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問