🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
JavaScript

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

jQuery

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

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

CSS

CSSはXMLやHTMLで表現した色・レイアウト・フォントなどの要素を指示する仕様の1つです。

Q&A

解決済

1回答

10994閲覧

SPレイアウトの時だけアコーディオン機能を実行したい

aKusano

総合スコア3763

JavaScript

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

jQuery

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

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

CSS

CSSはXMLやHTMLで表現した色・レイアウト・フォントなどの要素を指示する仕様の1つです。

0グッド

0クリップ

投稿2016/08/07 09:33

#やりたいこと
タイトルのとおりです。
レスポンシブサイトにおいて、639px以下のSPレイアウト時のみ、
通常のコンテンツをアコーディオン開閉式UIに変更するようにしたい。

#現状のソースコード

HTML

1<div class="js-accordion"> 2 <div class="js-acrTitle sp">【アコーディオンタイトル:ボタン機能】</div> 3 <div class="js-acrBody"> 4 【アコーディオンの中身】 5 </div><!-- /.js-acrBody --> 6</div><!-- /.js-accordion -->

CSS

1.sp {display:none;} 2@media screen and (max-width: 639px){ 3 .sp {display:block;} 4 .js-acrBody {display:none;} 5}

JavaScript

1$(function(){ 2 accrdion(); 3}); 4 5function accordion() { 6 var accordionOffset = []; 7 var $accordion = $(".js-accordion"); 8 9 10 var Accordion = { 11 getaccordionOffset: function () { 12 $accordion.each(function (i) { 13 accordionOffset[i] = $(this).offset().top; 14 }); 15 }, 16 hdlClick: function (Selector) { 17 var num = $(".js-acrTitle").index(Selector); 18 $("body,html").stop().animate({"scrollTop": accordionOffset[num] - 50}, 400, function () { 19 Accordion.getaccordionOffset(); 20 }); 21 if (Selector.hasClass("op")) { 22 Selector.removeClass("op"); 23 Selector.next().stop().slideUp(400, function () { 24 Accordion.getaccordionOffset(); 25 }); 26 } else { 27 Selector.next().stop().slideDown(400, function () { 28 Accordion.getaccordionOffset(); 29 }); 30 Selector.addClass("op"); 31 } 32 } 33 } 34 35 Accordion.getaccordionOffset(); 36 $(".js-acrTitle") 37 .on("click",function () { 38 Accordion.hdlClick($(this)); 39 }); 40}

#問題となっているところ
アコーディオンを開閉するタイトル部.js-acrTitleは、もともとPCレイアウト時は不要で、
SPレイアウト時だけ表示すればよかったので、最初は上記コードでうまく行っていました。
(PCレイアウト時にはそもそもトリガーとなる要素が無いので機能しない)
ところが、別のページでPCレイアウト時には開閉トリガー機能の無い見出しとして.js-acrTitleを表示し、
639px以下になったところでアコーディオンになるようにする、という変則バージョンのモジュールが出てきてしまいました。
上記スクリプトでは.js-acrTitleをクリックしたら開閉してしまうので、なんとかしてアコーディオン機能を639px以下の時だけに限定しようとしてif文を書いてみたりもしたのですが、うまくいきませんでした。

#実現したい仕様
1.PCレイアウト時にはただのコンテンツ
2.SPレイアウト時(639px以下)の時はアコーディオン機能
3.PCブラウザでブレイクポイントをまたぐ形で画面幅を変更した際にもアコーディオン機能の実行/停止が正しく判定されるようにする
4.SPでアコーディオン操作で.js-acrBodyを閉じた状態でPCレイアウトに変更した際も、表示状態を全てリセットして元に戻す
5.リサイズ時の判定・実行は、リサイズイベントが完了した時に1度だけ行われるように処理する(iPhoneのスクロール対策)

うまくいかなくて消してしまったので実際のコードを掲載できないのですが、上記仕様の内、1,2,4,5は実現できていました。
ただ、3の時にPC(アコーディオン無し)→SP(アコーディオン実行)は実現できましたが、一旦SPでアコーディオン機能を実行した後、ふたたびPCレイアウトに戻った時にアコーディオン機能を停止することがどうしてもできませんでした。

#教えてほしいこと
基本的にクリックしたタイミングとか、リサイズしたタイミングで画面幅$(window).width()を取得して、if文で条件分岐、ということをやっていたのですが、やりたい機能全体を通した場合のロジックがうまく作れないので、
どのタイミングで何を取得し、どう判定して何を実行したら良いのか というロジック部分を中心にご教授いただけますと大変助かります。
また、もし画面幅の取得で分岐する以外のもっとスマートな実装方法があるのだとしたら、知りたいです。
(※PC用の見出しとSP用の見出しを重複記述して表示/非表示切り替える手法はNGです)

長々と申し訳ありませんが、どなたかアドバイスいただけますと助かります。
よろしくお願い申し上げます。

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

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

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

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

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

guest

回答1

0

ベストアンサー

リサイズ時に取得しておいて、クリック時に判断すれば良いと思います。また、私は画面幅で切り替えればよいと思います。特に画面幅に合わせたデザインにしているのであれば、デザインの切り替わりと機能の切り替わりは同じタイミングでよいと思います。

JavaScript

1var sp_flag = false; 2// リサイズ時に取得しておいて、 3$( window ).on( 'load resize', function() { 4 sp_flag = ( window.matchMedia( '(max-width:639px)' ).matches ); // IE10+ 5} ); 6$( '.js-acrTitle' ).on( 'click', function() { 7 // クリック時に判断すれば良いと思います。 8 if ( sp_flag ) { 9 Accordion.hdlClick( $( this ) ); 10 } 11} );

【Media Queries(メディアクエリ)とJavaScriptの連携について - Qiita】
http://qiita.com/r_abe01/items/a3a2e94b5162d949037b

【window.matchMedia - Web API インターフェイス | MDN】
https://developer.mozilla.org/ja/docs/Web/API/Window/matchMedia

投稿2016/08/07 09:56

kei344

総合スコア69596

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

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

aKusano

2016/08/07 16:34

ご回答有り難うございます。 まだ試せていないのですが、確認次第ご報告させていただきたいと思います。 window.matchMedia()というのは初めて見ました。 参考サイトの方も情報ありがとうございます。参考にさせていただきます。 が、うっかりしていましたがこの案件、IE9が対象に入っていたりします。。 window.matchMediaはIE10+でないと効かないんですよね? IE9も対象とした場合はUA分岐して別の方法で対処、でしょうか?
kei344

2016/08/07 16:43

var w = window.innerWidth ? window.innerWidth : $( window ).width(); sp_flag = ( w <= 639 ); 普通に画面幅を取る、でいいと思います。両方使う( matchMedia を基本に、無ければ幅で)という手段もありますね。 if ( window.matchMedia ) { sp_flag = ( window.matchMedia( '(max-width:639px)' ).matches ); // IE10+ } else { var w = window.innerWidth ? window.innerWidth : $( window ).width(); sp_flag = ( w <= 639 ); }
aKusano

2016/08/07 16:48

なるほど。ちょっとやってみますね。 いつもありがとうございます!
aKusano

2016/08/09 11:32

ご報告遅くなりまして申し訳ありません。 教えていただいたロジックで組んでみたところ、無事実現したい仕様を実装することができました! 正直まだどうしてこのロジックならうまくいくのかちゃんと理解はできていないのですが、 この後じっくり考えてみたいと思います。 取り急ぎ御礼とご報告まで。 ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問