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

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

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

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

jQuery

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

Q&A

解決済

1回答

2479閲覧

jQuery:sectionに対応したtriggerで変わるサイドメニュー

rayco

総合スコア11

JavaScript

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

jQuery

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

0グッド

0クリップ

投稿2017/01/19 02:00

編集2017/01/19 03:05

###前提・実現したいこと
実現したいこと:
・上下スクロール時に複数設定したsectionのトリガー到達時に合致するサイドメニューを切り替える。
・対象コンテンツを過ぎたらサイドメニューは隠す。

前提:
・フル画面ページではない。
・sectionは縦並びで9個、うちサイドメニュー対象は上部5個。
・スクロールを戻すとサイドメニューの内容も戻る。
・サイドメニューはz-indexなどで重ねsectionと合致する内容のみ表示する。
・レスポンシブ対応(※スマホ・タブレット時はサイドメニューは非表示)
・サイドメニューは上部固定。

近い動作をするサイト
http://springsummer.dk/

###発生している問題
トリガー前にサイドメニューが切り替わる、もしくはトリガーを超えてから切り替わってしまう。
サイドメニュー対象外のエリアに入ってもサイドメニューが消えない。

###該当のソースコード
HTML

<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <meta name="format-detection" content="telephone=no"> <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=yes"> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script> <script src="js/jquery.bxslider.min.js"></script> <script> $(function() { // 引き金となる要素を設定 var triggerNode = $(".trigger"); // 画面スクロール毎に判定を行う $(window).scroll(function(){ // 引き金となる要素の位置を取得 var triggerNodePosition = $(triggerNode).offset().top - $(window).height(); // 現在のスクロール位置が引き金要素の位置より下にあれば‥ if ($(window).scrollTop() > triggerNodePosition) { // なんらかの命令を実行 $('#sidenav').addClass('on'); } }); }); $(function(){ var margin = -250, sectionTop = new Array, current = -1; $('.trigger').each(function(i) { sectionTop[i] = $(this).offset().top; }); $('#sidenav').append('<div id="#current"></div>'); //create #current changeNavCurrent(0); $(window).scroll(function(){ scrollY = $(window).scrollTop(); for (var i = sectionTop.length - 1 ; i >= 0; i--) { if (scrollY > sectionTop[i] - margin) { changeNavCurrent(i); break; } }; }); //ナビの処理 function changeNavCurrent(curNum) { if (curNum != current) { current = curNum; curNum2 = curNum + 1; $('#sidenav li').removeClass('on'); $('#sidenav li:nth-child(' + curNum2 +')').addClass('on'); /* 位置によって個別に処理をしたい場合 if (current == 0) { // 現在地がsection1の場合の処理 } else if (current == 1) { // 現在地がsection2の場合の処理 } else if (current == 2) { // 現在地がsection3の場合の処理 }*/ } }; }); $(function(){ $(window).scroll(function(){ var obj_t_pos = $('#moreContents').offset().top; var scr_count = $(document).scrollTop() + (window.innerHeight/2); // ディスプレイの半分の高さを追加 if(scr_count > obj_t_pos){ $('#sidenav').addClass('cle'); }else{ $('#sidenav').removeClass('cle'); } }) }); </script> </head> <body> <div id="Contents"> <div id="Main"> <div id="mainContents"> <div class="trigger" id="section01"> 内容1:スライダー(bxslider) </div> <div class="trigger" id="section02"> 内容2 </div> <div class="trigger" id="section03"> 内容3 </div> <div class="trigger" id="section04"> 内容4 </div> <div class="trigger" id="section05"> 内容5 </div> </div> <div id="moreContents"> <div class="otherContents" id="sub01"> 内容6 </div> <div class="otherContents" id="sub02"> 内容7 </div> <div class="otherContents" id="sub03"> 内容8 </div> <div class="otherContents" id="sub04"> 内容9 </div> </div> <ul id="sidenav"> <li><a href="#section01">内容1タイトル</a></li> <li><a href="#section02">内容2タイトル</a></li> <li><a href="#section03">内容3タイトル</a></li> <li><a href="#section04">内容4タイトル</a></li> <li><a href="#section05">内容5タイトル</a></li> </ul> </div> </div> </body> </html>

###試したこと
ソースの書き換え、他のプラグインの使用など
複数ブラウザでの動作確認(IE、Firefox、Chrome)

初めまして、Webページを作成していて、どうしても解決できないのでお力添えをいただければと思います。
プラグインや、ネットに掲載されているソースをほんの少し触る程度の実力です。
よろしくお願いいたします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

これでいいでしょうか?
サイドメニューのidは'sideMenu'に変えました。

CSS

1#Contents { 2 position : relative; 3 left : 0px; 4 top : 0px; 5} 6 7#Main { 8 position : relative; 9 left : 0px; 10 top : 0px; 11} 12 13.trigger, .otherContents { 14 left : 100px; 15 height : 100%; 16 margin-top : 10px; 17 margin-bottom : 20px; 18} 19 20#sideMenu { 21 /* サイドメニューの位置は固定 */ 22 position : fixed; 23 left : 0px; 24 top : 60px; 25} 26 27#sideMenu li { 28 /* サイドメニューの全項目は原則非表示 */ 29 display : none; 30} 31 32#sideMenu li.on { 33 /* サイドメニューのCSSクラス'on'が追加されている項目は表示 */ 34 display : block; 35}

JavaScript

1$(function() { 2 // ブラウザの画面幅がこの値より狭くなると、サイドメニューは非表示 3 var discontinuousWidth = 760; 4 // 引き金となる要素 5 var triggerNode = $(".trigger"); 6 // 引き金となる各要素の(marginを含む)範囲(上、下)の配列 7 var triggerNodeRange = new Array(); 8 // サイドメニューで現在表示されている項目のsection番号(nullならば非表示) 9 var currentSection = null; 10 11 12 // 引き金となる各要素の範囲を一つずつ取得して配列に保存 13 triggerNode.each(function(index) { 14 var marginTop = $(this).css('margin-top'); 15 // 'px'を取り去って数値に変換 16 marginTop = marginTop.replace(/px$/, '') - 0; 17 18 var top = $(this).offset().top - marginTop; 19 // marginを含む高さを取得 20 var height = $(this).outerHeight() + marginTop; 21 var bottom = top + height - 1; 22 23 // 引き金要素の範囲(上と下をセットで)を配列要素に保存 24 triggerNodeRange[index] = { 25 'top' : top, 26 'bottom' : bottom 27 }; 28 }); 29 30 31 // サイドメニューに項目を初期表示 32 selectItemFromSideMenu(1); 33 34 35 // 画面スクロール時に動作 36 $(window).on('scroll', function() { 37 // 現在のスクロール位置 38 var scrollY = $(window).scrollTop(); 39 40 for (var sectionNum = 1; 41 sectionNum <= triggerNodeRange.length; 42 sectionNum++) 43 { 44 // 引き金となる各要素の範囲の配列から要素を取り出して比較 45 // (配列のindexは0から始まるので、section番号から1を引く) 46 var range = triggerNodeRange[sectionNum - 1]; 47 if (range.top <= scrollY && scrollY <= range.bottom) { 48 // 現在のスクロール位置が、引き金要素の上と下の間ならば、 49 // サイドメニューにsection番号の項目を表示 50 selectItemFromSideMenu(sectionNum); 51 return; 52 } 53 } 54 55 // どの引き金要素の範囲内になければ、 56 // サイドメニューの項目を非表示 57 selectItemFromSideMenu(null); 58 }); 59 60 61 // 画面幅変化時に動作 62 $(window).on('resize', function() { 63 selectItemFromSideMenu(currentSection); 64 }); 65 66 67 /** 68 * サイドメニューにsection番号の項目を表示 69 * @param sectionNum 項目を表示するsection番号(nullならば非表示) 70 */ 71 function selectItemFromSideMenu(sectionNum) { 72 currentSection = sectionNum; 73 74 // 全ての項目からCSSクラス'on'を削除 75 $('#sideMenu li').removeClass('on'); 76 77 if ($(window).width() >= discontinuousWidth && 78 currentSection !== null) { 79 // ブラウザの画面幅が広く、nullでなければ、 80 // currentSection番目の項目にCSSクラス'on'を追加 81 $('#sideMenu li:nth-child(' + currentSection + ')').addClass('on'); 82 } 83 } 84}); 85

投稿2017/01/21 02:25

編集2017/01/21 02:39
naomi3

総合スコア1105

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

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

rayco

2017/01/21 06:09

ご回答ありがとうございました。思っていた動作できました! コメントを入れていただいているおかげで、勉強にもなります。 本当にありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問