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

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

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

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

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

Q&A

解決済

3回答

7866閲覧

【jQuery】「レスポンシブ」Window幅を変えた場合に、リロード無しで別の動きをさせたい

umauman

総合スコア57

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

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

0グッド

0クリップ

投稿2017/03/14 09:13

編集2017/03/15 06:05

###前提
レスポンシブでグローバルナビゲーションを作っています。
ウィンドウの幅をドラッグして大きくしたり小さくしたりした場合に、リアルタイムでウィンドウ幅を感知して、スマートフォン、PCサイトで異なる動きをさせたく思っていますがうまくいきません。
※ウィンドウ幅感知の部分をのぞけば意図通りの動作をしています。

###実現させたい仕様
■スマートフォン(767pxまで)
二階層目があり、それも開閉


会社概要 ↓


商品 ↓


それぞれをクリックしたら二階層目が展開する。
矢印の向きが「↑」に変化し、クリックしたら再び閉じて「↓」になる。


会社概要 ↑


沿革


地図


商品 ↑


商品A


商品B


■PCサイト(768px以上)
クリックしても二階層目は開閉させない。

| 会社概要 | 商品 |

###現在の記述 ※「Window幅を感知して処理を変える」以外の部分は意図通り動作する

HTML

1<ul> 2 <li class="dropdown"><a href="#" class="open">会社概要</a> 3 <ul> 4 <li><a href="#">沿革</a></li> 5 <li><a href="#">地図</a></li> 6 </ul></li> 7 <li class="dropdown"><a href="#" class="open">商品</a> 8 <ul> 9 <li><a href="#">商品A</a></li> 10 <li><a href="#">商品B</a></li> 11 </ul></li> 12</ul>

JavaScript

1$(window).on('load resize', function(){//window幅に変更があった場合に感知させたい(が、うまくいっていない) 2 if( window.matchMedia('(max-width:767px)').matches ){//スマートフォンの場合 3 $('.dropdown').on('click','> .open', function(e){ 4 e.preventDefault(); 5 $(this).next('ul') 6 .slideDown('fast', function(){ 7 $(this).prev('.open').removeClass().addClass('close'); 8 }) 9 }).on('click','> .close', function(e){ 10 e.preventDefault(); 11 $(this).next('ul') 12 .slideUp('fast', function(){ 13 $(this).prev('.close').removeClass().addClass('open'); 14 }) 15 }); 16 }else{//それ以外(PCの場合) 17 $('.dropdown').children('a').next('ul').hide(); 18 } 19});

CSS

1@media only screen and (max-width: 767px) { 2 .dropdown > .open::after { 3 content: '↓'; 4 } 5 .dropdown > .close::after { 6 content: '↑'; 7 } 8} 9@media only screen and (min-width: 768px) { 10 .dropdown ul{ 11 //今のところ特に何も記述はしていないが display:none !important;を入れるべき?(後述) 12 } 13}

上記の記述で、PC幅でリロード、スマートフォン幅でリロードした場合、それぞれ意図した動きになっています。
ただ、ウィンドウの幅をマウスをドラッグして変更した時下記の動きになります。

①最初PCウィンドウ→②スマートフォンサイズにせまくする→③再びPCウィンドウサイズにする

①、②までは意図通りの動きをします。
③になると「会社概要」や「商品」をクリックすると二階層目が展開されるようになってしまいます。

###補足
そもそもウィンドウの幅を任意で変えるユーザーはいないような気もしますのでこのような処理は必要ないのかもしれませんが向学のため、なぜ条件分岐通りに動かないのか知りたく思っています。

またCSSのメディアクエリ「min-width:768px」で二階層目のメニューを「display: none !important;」で非表示にしたら良いかとも思ったのですが、

①最初PCウィンドウ→②スマートフォンサイズにせまくする→③再びPCウィンドウサイズにする
上記のステップの①で一階層目のメニューをクリックしてから②にすると二階層目が展開されない状態で矢印が上を向いてしまいます。


ウィンドウサイズを変更した場合、リロード無しでPC⇔スマートフォンでそれぞれ仕様通りの動きを反映させるにはどのように記述をするべきなのでしょうか?ご教授いただけますと助かります。どうぞよろしくお願いいたします。

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

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

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

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

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

guest

回答3

0

ベストアンサー

質問の回答というわけでは無いですが、
レスポンシブだとフラグ管理が複雑になってしまうので、
自分の場合、極力CSSのメディアクエリでimportant指定をして、
動きを固定するようにしていますね。

例えば、スマホサイズの時サブメニューが展開される部分を、
PCサイズではimportant指定で展開されない様にします。

投稿2017/03/16 03:06

KakeruKaneko

総合スコア115

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

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

umauman

2017/03/16 07:07

ご回答ありがとうございます。 先にご回答いただいた方々の方法で実現をしてみたかったのですが、スキル不足で叶わず… 加えて、調べていくうちに、アドバイスの通り、PCサイズでは二階層目を「display:none !important」で見えないようにするのが一番良い方法なのかと思いました。補足に書いたような不具合はあるのですが、スマートフォンだとウィンドウ幅も変えられないので… 特に今回のようなケースはWindow Resizeの囲みは削除し、単にif( window.matchMedia('(max-width:767px)').matches ){}のみ残すシンプルなもので良いのかと思いました。 再度、ありがとうございました。
guest

0

ざっとしか見ていませんが、(例えば)下記のような書き方をすると resize イベントが起こるたびに .openclick イベントが設定されます。

JavaScript

1$( window ).on( 'load resize', function() { 2 $( '.open' ).on( 'click', function() {} ); 3} ); // 説明のために簡略化

処理によりますが、matchMedia の状態をリサイズ時に保存して、クリック時にそれを確認するのが良い気がします。(クリックイベントを毎回外す事も出来ますが)

JavaScript

1var flag = false; 2$( window ).on( 'load resize', function() { 3 flag = ( window.matchMedia('(max-width:767px)').matches ); // 状態を保存 4} ); 5$( function() { 6 $( '.open' ).on( 'click', function() { 7 if ( flag ) { 8 9 } else { 10 11 } 12 } ); 13} );

あと多分転記ミスだと思いますが、$(this).next('close')$(this).next('.close') では?

投稿2017/03/14 17:30

kei344

総合スコア69400

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

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

umauman

2017/03/15 06:49

ご回答ありがとうございます。記述ミスもすみません。ご指摘とても助かりました。 下記のように記述をしてみましたが、「①PC→②スマートフォン→③PC」の③で二階層目のドロップダウンができてしまいます。ウィンドウ幅を変更した後にリロードするとPC、スマートフォンそれぞれ意図した通りの動作になります。(質問欄に記述したソースと同じ結果です) 後は $( '.open,.close' ).onにしてみたり色々試しているところです。 var flag = false; $( window ).on( 'load resize', function() { flag = ( window.matchMedia('(max-width:767px)').matches ); // 状態を保存 } ); $( function() { $( '.open' ).on( 'click', function() { if ( flag ) { $('.dropdown').on('click','> .open', function(e){ e.preventDefault(); $(this).next('ul') .slideDown('fast', function(){ $(this).prev('.open').removeClass().addClass('close'); }) }).on('click','> .close', function(e){ e.preventDefault(); $(this).next('ul') .slideUp('fast', function(){ $(this).prev('.close').removeClass().addClass('open'); }) }); } else { $('.dropdown').children('a').next('ul').hide(); } } ); } );
kei344

2017/03/15 07:40

やっていることが同じで、イベントの中でイベントを追加していることが変わりません。
umauman

2017/03/15 09:11

なかなか理解が足りず本当に申し訳ございません。 変数を使って先に記述することに意味がありそうだと思いました。 ifとelseで同一のセレクタに対して分岐をすればうまくいくところまでわかってきたのですが、もうちょっとシンプルにして質問をし直しました。 https://teratail.com/questions/69215 本質問に追記すべきか悩んだのですが、若干質問内容の方向性が変わってしまったので、新しい質問にしました。 もし差し支えなければ再び助けていただけるととてもありがたく思います。
kei344

2017/03/15 09:33

> 変数を使って先に記述 $.on( いべんと, function() {この中でイベントを登録したら「いべんと」が起こるたびに中で設定したイベントも増え続ける}); ということを言っているのですが、もう少し上手い説明が必要そうですね。お役に立てなかったようで残念です。 > 新しい質問 そちらの質問が解決した際にはこちらに解決方法を書き、「解決済」にしてくださいね。 がんばってください!
umauman

2017/03/15 09:52

わざわざご返信ありがとうございます。 ご説明いただいた内容をもう少し落ち着いて理解してみるよう引き続き努力をしてみます。 >そちらの質問が解決した際にはこちらに解決方法を書き、 >「解決済」にしてくださいね。 こちらもアドバイスありがとうございます。 新しい質問へのリンクを追記欄を設けて貼って誘導したら良いのか、 でもそれだけだと解決にはできないし…と悩んでいたので助かります!
guest

0

こういうことでしょうか。
デモ

投稿2017/03/14 09:43

turbgraphics200

総合スコア4267

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

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

umauman

2017/03/14 10:16

早速ありがとうございます! 記述いただいたコードを拝見しましたが、下記動作になりました。 ①最初にPCサイト幅→②スマートフォン幅→③もう一度PC幅 ①【PC】二階層目のメニューが展開されています。 ②【スマホ】二階層目がクリックしても展開されません。 ③【PC】希望する動きです。(クリックしても展開できない) ①最初にスマートフォン幅→②PCサイト幅→③もう一度スマートフォン幅 ①【スマホ】二階層目が最初から展開されています。 ②【PC】希望する動きです。(クリックしても展開できない) ③【スマホ】二階層目がクリックしても展開されません。 希望としては下記なのですが、どのように記述をしたら良いでしょうか。 ①最初にPCサイト幅→②スマートフォン幅 ①【PC】クリックしても二階層目が展開されないようにしたい ②【スマホ】クリックした場合二階層目が展開されるようにしたい ①最初にスマートフォン幅→②PCサイト幅 ①【スマホ】クリックした場合二階層目が展開されるようにしたい ②【PC】クリックしても二階層目が展開されないようにしたい 「addListener」調べましたが、便利そうですね。 これを使う方のが良いかもしれないと思いました。色々試してみます。
umauman

2017/03/14 12:05 編集

何度も申し訳ございません。 キャッシュをクリアしたり、ブラウザを変更してみたりしたのですが、 なかなか希望通りの動きになりません; 下記のような動きになることを確認しました。 ①最初にPCサイト幅→②スマートフォン幅→③もう一度PC幅 ①【PC】二階層目のメニューが展開されています。 ②【スマホ】二階層目が展開されています。クリックをしたら第二階層が開閉します(後者の部分の動きは希望通りです) ③【PC】二階層目のメニューが閉じるものの、クリックをしたら第二階層が開閉します。(前者の部分は希望通りです) ①最初にスマートフォン幅→②PCサイト幅→③もう一度スマートフォン幅 ①【スマホ】二階層目が最初から展開されています。クリックしても第二階層が開閉しません。 ②【PC】二階層目のメニューが閉じるものの、クリックをしたら第二階層が開閉します。(前者の部分は希望通りです) ③【スマホ】二階層目のメニューが展開されています。クリックしたら第二階層が開閉します(後者の部分は希望通りです) 説明が悪いのかもしれませんが、下記のようなものを希望しております。 PC・・・第二階層がない(ドロップダウンしない)シンプルなグローバルナビゲーションとして見せたい。 スマートフォン・・・第二階層が開閉するグローバルナビゲーションとして見せたい。 本当に何度もありがとうございます。(と申し訳ない気持ちです。説明が下手なのだと思います)
umauman

2017/03/14 13:35

再度、ご回答ありがとうございます。 ほぼ意図する動きなのですが、スマートフォン幅で見ると二階層目のナビゲーションが最初から開いた状態になっています。 後は…なかなか初心者にはハードルの高いソースになってきました(悲) CSSのメディアクエリのようにウィンドウ幅をリアルタイルに判定して、動きを変えるみたいなことは、jQuery(JavaScript)だと、もしかするとそこまで簡単にはいかなかったりするのでしょうか… 何度もお付き合いいただいており、本当にすみません。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問