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

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

ただいまの
回答率

88.57%

スクロール位置でナビゲーションに変化をつけたい

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 2,347

shomo

score 8

スクロールに合わせてコンテンツの位置を取得し、ナビゲーションの色を薄くして、かつアンダーラインを入れたいと思っています。
https://www.tam-tam.co.jp/tipsnote/javascript/post4996.html
こちらのサイトを参考にして作成していますが、全く反応もなく、検証ツールでは$(targetContents).offset().top;に取得できないとエラー文が出ています。
どのようにすれば、うまくいくのでしょうか。

$(function(){
      var navLink = $('#gnav li a');

      var contentsArr = new Array();
      for (var i = 0; i < navLink.length; i++) {
          var targetContents = navLink.eq(i).attr('href');
if(targetContents.charAt(0) == '#') {
    var targetContentsTop = $(targetContents).offset().top;
    var targetContentsBottom = targetContentsTop + $(targetContents).outerHeight(true) - 1;
         // 配列に格納
            contentsArr[i] = [targetContentsTop, targetContentsBottom]
      }
   };

  // 現在地をチェックする
   function currentCheck() {
       // 現在のスクロール位置を取得
        var windowScrolltop = $(window).scrollTop();
        for (var i = 0; i < contentsArr.length; i++) {
           // 現在のスクロール位置が、配列に格納した開始位置と終了位置の間にあるものを調べる
          if(contentsArr[i][0] <= windowScrolltop && contentsArr[i][1] >= windowScrolltop) {
                // 開始位置と終了位置の間にある場合、ナビゲーションにclass="current"をつける
               navLink.removeClass('current');
               navLink.eq(i).addClass('current');
                i == contentsArr.length;
            }
       };
  }

   // ページ読み込み時とスクロール時に、現在地をチェックする
  $(window).on('load scroll', function() {
      currentCheck();
 });

 // ナビゲーションをクリックした時のスムーズスクロール
    navLink.click(function() {
      $('html,body').animate({
          scrollTop: $($(this).attr('href')).offset().top
       }, 300);
        return false;
   })
});
<ul id="gnav" class="navigation-list">
                <li class="list-item"><a href="#top" class="underline side">Home</a></li>
                <li class="list-item"><a href="#about" class="underline side">About</a></li>
                <li class="list-item"><a href="#case-studies" class="underline side">Case studies</a></li>
...
#gnav a {
    text-decoration: none;
    color: #000000;
    transition: border-color 0.3s, color 0.3s;
}

#gnav a .current {
    color: #1d3d36;
    opacity: 0.6;
}
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

このコードでいくなら、まず#gnavのaにidを振らないと駄目ですよ。

<ul id="gnav" class="navigation-list">
  <li class="list-item"><a id="top" href="#top" class="underline side">Home</a></li>
  <li class="list-item"><a id="about" href="#about" class="underline side">About</a></li>
  <li class="list-item"><a id="case-studies" href="#case-studies" class="underline side">Case studies</a></li>
...

で、scriptは
var targetContentsTop = $(targetContents).offset().top;
の書き方を修正。

$(function(){
      var navLink = $('#gnav li a');

      var contentsArr = new Array();
      for (var i = 0; i < navLink.length; i++) {
          var targetContents = navLink.eq(i).attr('href');
if(targetContents.charAt(0) == '#') {
    var targetContentsTop = $('' + targetContents + '').offset().top;
    var targetContentsBottom = targetContentsTop + $(targetContents).outerHeight(true) - 1;
         // 配列に格納
            contentsArr[i] = [targetContentsTop, targetContentsBottom]
      }
   };

  // 現在地をチェックする
   function currentCheck() {
       // 現在のスクロール位置を取得
        var windowScrolltop = $(window).scrollTop();
        for (var i = 0; i < contentsArr.length; i++) {
           // 現在のスクロール位置が、配列に格納した開始位置と終了位置の間にあるものを調べる
          if(contentsArr[i][0] <= windowScrolltop && contentsArr[i][1] >= windowScrolltop) {
                // 開始位置と終了位置の間にある場合、ナビゲーションにclass="current"をつける
               navLink.removeClass('current');
               navLink.eq(i).addClass('current');
                i == contentsArr.length;
            }
       };
  }

   // ページ読み込み時とスクロール時に、現在地をチェックする
  $(window).on('load scroll', function() {
      currentCheck();
 });

 // ナビゲーションをクリックした時のスムーズスクロール
    navLink.click(function() {
      $('html,body').animate({
          scrollTop: $($(this).attr('href')).offset().top
       }, 300);
        return false;
   })
});

あと、CSS

#gnav a {
    text-decoration: none;
    color: #000000;
    transition: color 0.3s;
    border-bottom:1px solid transparent;
}

#gnav a.current {
    color: #1d3d36;
    opacity: 0.6;
    border-bottom-color: #1d3d36;
}

以上です。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/08/30 18:53

    回答ありがとうございます。
    こちらからの返信が大変遅くなり申し訳ございません。

    お話にならない←大変失礼いたしました。

    もう一度やってみたところ、スクロールしてナビが変化したのですが、変化させたいナビゲーションでないナビゲーションが変化します。
    すみません、これはもう一度自分で解読しなくてはと思っている中、まだ手がつけられていなく、ご連絡が遅くなりました。

    キャンセル

  • 2018/08/31 10:31

    返信が遅くなっても全然かまいませんよ。

    で、変化はするが期待した動作ではなかったとのことですが(←こちらの想定通りです。あとはご自身で調整するものだと思っておりました。)
    ご質問内容にも、また、ご提示のソースで推測してもshomoさんがどうしたいのかは分からないです。
    参考サイトはHTMLのソースにコンテンツをしっかりと記載されておりますが、ご提示のHTMLにはナビゲーションしか記載されておりません。(しかも、途中で略されてるよー)

    なので、しっかりとご自身の環境(そのままでなくて良いので、この場合再現できる内容)をご提示くださいな。

    キャンセル

  • 2018/09/10 08:32

    また、遅くなり申し訳ございません。

    質問の仕方が間違っていること、大変失礼いたしました。

    あとはご自身で調整するものだと思っておりました。
    ←すみません、まだ勉強始めでわかっていないまま質問投稿していました。

    言い訳ばかりの返信になり、自分の勉強不足の状態での質問投稿に情けないばかりです。
    改めてYousuckさんに質問できるように今一度自分で考え直します!!!!!!

    キャンセル

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

  • ただいまの回答率 88.57%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る