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

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

ただいまの
回答率

91.26%

  • JavaScript

    11747questions

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

  • HTML

    6429questions

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

  • jQuery

    5045questions

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

  • CSS

    4056questions

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

jQueryを使ったjsの綺麗な書き方について

解決済

回答 4

投稿 編集

  • 評価
  • クリップ 3
  • VIEW 600

SaekoIwaki

score 25

いつもお世話になっております。
今回はjsの正しい書き方についてお聞きしたく、ご質問をさせていただきます、

現状

ヘッダーが追従ナビゲーションになっており、スクロールするとナビゲーションに
カレントclassが付与される仕組みです。
動作の方は問題なく動いております。

問題点

jsの書き方が冗長であるため、どのように、記述すれば綺麗にかけますでしょうか。
自分にとっての難点が、メニューにない部分はカレントclassを付けないため、メニューの関係無いスクロール量の場合は
カレントを消すようにしています。ここの部分の書き方が冗長的です。また、.eq(n)でclassを与えてるため、メニューが
増えたり減ったりした場合、番号をずらさないといけないため、応用が効かない書き方とも思っています。

無駄のない書き方があればご教授していただければ幸いです。
DEMOをアップ致しました。
HTML

<!doctype html>
/*~省略~*/
<body id="top">
    <header>
        <nav>
            <ul>
                <li class="current"><a href="#top">1番</a></li>
                <li><a href="/hoge/">2番</a></li>
                <li><a href="#03">3番</a></li>
                <li><a href="#04">4番</a></li>
                <li><a href="#05">5番</a></li>
                <li><a href="#06">6番</a></li>
            </ul>
        </nav>
    </header>
    <main>
        <article>
            <section class="col1">セクション01</section>
            <section class="col2">セクション02</section>
            <section class="col3" id="03">3番</section>
            <section class="col4" id="04">4番</section>
            <section class="col5" id="05">5番</section>
            <section class="col1">セクション</section>
            <section class="col2">セクション</section>
            <section class="col3">セクション</section>
            <section class="col4" id="06">6番</section>
            <section class="col5">セクション</section>
        </article>
    </main>
<script
  src="https://code.jquery.com/jquery-1.12.4.js"
  integrity="sha256-Qw82+bXyGq6MydymqBxNPYTaUXXq7c8v3CwiYwLLNXU="
  crossorigin="anonymous"></script> 
<script src="/js/main.js"></script> 
</body>
</html>


js

$(function(){
    var header = ('header');
    var headerheight = $(header).outerHeight();
    var heightFunc = function () {
        var mainheight = $('main').css('padding-top', headerheight);
    }
    heightFunc();

    $('a[href^="#"]').on('click', function () {
        var Href;
        var position ;
        Href = $(this).attr("href");
        position = $(Href).offset().top;
        $('body,html').animate({
            scrollTop: position - headerheight
        }, 800, 'swing');
        return false;
    });

    var currentFunc = function () {
        var sectionTop = new Array;
        var nowScroll;
        $('section').each(function (i) {
            sectionTop[i] = $(this).offset().top;
            sectionTop[i] = sectionTop[i] - headerheight;
        });
        $(window).scroll(function () {
            nowScroll = $(window).scrollTop();
            if (sectionTop[0] <= nowScroll && sectionTop[1] > nowScroll) {
                $('header nav ul li').eq(0).addClass('current');
            } else {
                $('header nav ul li').eq(0).removeClass('current');
            }
            if (sectionTop[2] <= nowScroll && sectionTop[3] > nowScroll) {
                $('header nav ul li').eq(2).addClass('current');
            } else {
                $('header nav ul li').eq(2).removeClass('current');
            }
            if (sectionTop[3] <= nowScroll && sectionTop[4] > nowScroll) {
                $('header nav ul li').eq(3).addClass('current');
            } else {
                $('header nav ul li').eq(3).removeClass('current');
            }
            if (sectionTop[4] <= nowScroll && sectionTop[5] > nowScroll) {
                $('header nav ul li').eq(4).addClass('current');
            } else {
                $('header nav ul li').eq(4).removeClass('current');
            }
            if (sectionTop[8] <= nowScroll && sectionTop[9] > nowScroll) {
                $('header nav ul li').eq(5).addClass('current');
            } else {
                $('header nav ul li').eq(5).removeClass('current');
            }
        });
    }
    currentFunc();
});
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • SaekoIwaki

    2017/12/13 23:13 編集

    masaya_ohashi様 ご連絡が遅れてすいません。 セクション2の範囲は3番扱いでは無いと思いますが。。。ナビゲーションの3番を押下するとちゃんと三つ目のsectionに移動すると思います。また、「idが割り当てられていないセクションのときはどのヘッダもcurrentにならない仕様」についてですが、おっしゃる通りの認識で問題ないです。ちょっと変な仕様ではありますが。。。

    キャンセル

  • karamarimo

    2017/12/14 00:44

    masaya_ohashiさんがおっしゃったのは、"sectionTop[1] <= nowScroll && sectionTop[3] > nowScroll"の部分だと思います。これだとセクション02と3にいるときに3番目のヘッダーがハイライトされますよね。

    キャンセル

  • SaekoIwaki

    2017/12/14 01:01

    karamarimo様 おっしゃる通り確認しましたら確かにハイライトされていましたね。。。ですのでそこの部分はただのミスです。失礼しました。

    キャンセル

回答 4

checkベストアンサー

+2

以下のような内容ではどうでしょうか?

<!doctype html>
<!--[if lt IE 7]> <html class="ie6 oldie"> <![endif]-->
<!--[if IE 7]>    <html class="ie7 oldie"> <![endif]-->
<!--[if IE 8]>    <html class="ie8 oldie"> <![endif]-->
<!--[if gt IE 8]><!-->
<html class="">
<!--<![endif]-->
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Untitled Document</title>
<link href="/css/style.css" rel="stylesheet" type="text/css">
</head>
<!-- bodyのidを移動 -->
<body>
    <header>
        <nav>
            <ul>
                <li class="current"><a href="#top">1番</a></li>
                <li><a href="/hoge/">2番</a></li>
                <li><a href="#03">3番</a></li>
                <li><a href="#04">4番</a></li>
                <li><a href="#05">5番</a></li>
                <li><a href="#06">6番</a></li>
            </ul>
        </nav>
    </header>
    <main>
        <article>
            <!-- bodyのidはこちらに移動 -->
            <section class="col1" id="top">セクション01</section>
            <section class="col2">セクション02</section>
            <section class="col3" id="03">3番</section>
            <section class="col4" id="04">4番</section>
            <section class="col5" id="05">5番</section>
            <section class="col1">セクション</section>
            <section class="col2">セクション</section>
            <section class="col3">セクション</section>
            <section class="col4" id="06">6番</section>
            <section class="col5">セクション</section>
        </article>
    </main>
<script
  src="https://code.jquery.com/jquery-1.12.4.js"
  integrity="sha256-Qw82+bXyGq6MydymqBxNPYTaUXXq7c8v3CwiYwLLNXU="
  crossorigin="anonymous"></script>
<script src="/js/main.js"></script>
</body>
</html>
$(function() {
  var header = ('header');
  var headerheight = $(header).outerHeight();
  var heightFunc = function() {
    var mainheight = $('main').css('padding-top', headerheight);
  }
  heightFunc();

  $('a[href^="#"]').on('click', function() {
    var Href;
    var idxTargetposition;
    Href = $(this).attr("href");
    var position = $(Href).offset().top;
    $('body,html').animate({
      scrollTop: position - headerheight
    }, 800, 'swing');
    return false;
  });

  // ここから下が変更箇所
  var $nav = $('nav');

  // has関数の参考
  // http://taneppa.net/jq_filter/
  // a[href^="#"]の参考
  // http://weboook.blog22.fc2.com/blog-entry-268.html#b2
  var $lists = $nav.find('li').has('a[href^="#"]');

  var update = function() {
    var currentTop = $(window).scrollTop() + headerheight;
    $lists.removeClass('current');

    $lists.each(function() {
      var $list = $(this);
      var $anchor = $list.find('a');
      var href = $anchor.attr('href');
      var $section = $(href);

      if ($section.length > 0) {
        var sectionTop = $section.offset().top;
        var sectionBottom = sectionTop + $section.outerHeight();

        if (currentTop >= sectionTop && currentTop < sectionBottom) {
          $list.addClass('current');
        }
      }

    });
  };

  $(window).on('scroll resize', function() {
    update();
  });
  update();
});

注意点として、JSをシンプルに記述するために#topをbodyではなく最初のsectionに移動しています。

というのも、他はsectionにidを付けているのに#topだけbodyに付けてしまうと例外的な処理をJSでする必要があるためです。

動作的には同じ動作をするようになっていますが、どうしてもbodyに#topを付ける必要がある場合はJSにif文等で例外的な処理が必要になります。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/12/14 23:54

    style.cssの内容が提示されていると、回答者は検証しやすいでしょう。

    キャンセル

  • 2017/12/15 00:01

    style.cssに関しては質問者の方が提示されたデモから変更していないため省略しました。

    キャンセル

  • 2017/12/15 00:07

    すみません、勘違いしてました。アイコンがデフォルトだったので、質問者ご本人だと思い込んでました。

    キャンセル

  • 2017/12/15 00:10

    いえいえ、構わないですよ。確かに紛らわしいですしね

    キャンセル

  • 2017/12/15 23:19

    sdmilieu様
    ご回答ありがとうございました。
    こちらも後出しで申し訳ないですが(後出しと言うより単純に作りをシンプルにし過ぎたためすっかり大事なことを忘れていました)、ナビゲーションメニューの2番めに相当するのがセクション02に相当するところであり、スクロールした時にカレントが付く様な仕様です。

    イメージ的には、ナビゲーション2番がnews一覧ページに遷移し、トップページにnewsが数件表示されているデザインのようなイメージです。

    大変失礼しました。
    しかし、提示して頂いたコードの応用で条件分岐させれば出来る様な気がしてきました。プログラムの書き方も自分のと違うため勉強になりました。頂いたコードで試行錯誤してみみます。
    ありがとうございました!

    キャンセル

+1

こんな感じに仕上げてみました!
良かったらどうぞ~

<!doctype html>
<!--[if lt IE 7]> <html class="ie6 oldie"> <![endif]-->
<!--[if IE 7]>    <html class="ie7 oldie"> <![endif]-->
<!--[if IE 8]>    <html class="ie8 oldie"> <![endif]-->
<!--[if gt IE 8]><!-->
<html class="">
<!--<![endif]-->
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Untitled Document</title>
<link href="css/style.css" rel="stylesheet" type="text/css">
</head>
<body id="top">
    <header>
        <nav>
            <ul>
                <li class="current"><a href="#col01">1番</a></li>
                <li><a href="#col02">2番</a></li>
                <li><a href="#col03">3番</a></li>
                <li><a href="#col04">4番</a></li>
                <li><a href="#col05">5番</a></li>
                <li><a href="#col06">6番</a></li>
            </ul>
        </nav>
    </header>
    <main>
        <article>
            <section class="col1" id="col01">セクション01</section>
            <section class="col2" id="col02">セクション02</section>
            <section class="col3" id="col03">3番</section>
            <section class="col4" id="col04">4番</section>
            <section class="col5" id="col05">5番</section>

            <section class="col4" id="col06">6番</section>

        </article>
    </main>
<script
  src="https://code.jquery.com/jquery-1.12.4.js"
  integrity="sha256-Qw82+bXyGq6MydymqBxNPYTaUXXq7c8v3CwiYwLLNXU="
  crossorigin="anonymous"></script> 
<script src="/js/main.js"></script> 
</body>
</html>
$(function(){

    var header = $('header');
    var headerheight = header.outerHeight();
    var heightFunc = function () {
        $('main').css('padding-top', headerheight);
    }

    var currentFunc = function () {
        var sectionTop = new Array;
        var nowScroll;
        $('section').each(function (i) {
            sectionTop[i] = $(this).offset().top;
            sectionTop[i] = sectionTop[i] - headerheight;
        });
        $(window).scroll(function () {
            var list = $('header nav ul li');
            var classCurrent = 'current';
            var sectionTopLen = sectionTop.length-1;            
            nowScroll = $(window).scrollTop();

            for(var ii = 0; ii <= sectionTopLen ; ii++){

                if(ii === sectionTopLen){
                    if (sectionTop[ii] <= nowScroll) {
                        list.eq(ii).addClass(classCurrent);
                    }else{
                        list.eq(ii).removeClass(classCurrent);
                    }
                }else{
                    if(sectionTop[ii] <= nowScroll && sectionTop[ii+1] > nowScroll) {
                        list.eq(ii).addClass(classCurrent);
                    }else{
                        list.eq(ii).removeClass(classCurrent);
                    }
                }
            }

        });
    }

    $('a[href^="#"]').on('click', function () {
        var Href;
        var position ;
        Href = $(this).attr("href");
        position = $(Href).offset().top;
        $('body,html').animate({
            scrollTop: position - headerheight
        }, 800, 'swing');
        return false;
    });
    heightFunc();
    currentFunc();

});

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/12/13 23:17

    Yousuck様
    ご回答ありがとうございます!!
    試しに動かしてみて順にソースコードを理解してみますので、しばしお待ち下さい。
    ありがとうございました。

    キャンセル

  • 2017/12/14 22:39

    Yousuck様
    ご連絡が遅れてすいません。
    実際に提示して頂いたコードで試しましたが、各セクションを通過すると
    順番ずつにナビゲーションにカレントがつくみたいです。。。
    普通のナビゲーション(liの個数)とセクション(セクションの個数)が連動している感じになっていますね。。。6個目のセクションを過ぎたらカレントがつかなくなってしまうのでこの動きではちょっと違いますね。

    キャンセル

  • 2017/12/14 22:39

    Yousuck様
    ご連絡が遅れてすいません。
    実際に提示して頂いたコードで試しましたが、各セクションを通過すると
    順番ずつにナビゲーションにカレントがつくみたいです。。。
    普通のナビゲーション(liの個数)とセクション(セクションの個数)が連動している感じになっていますね。。。6個目のセクションを過ぎたらカレントがつかなくなってしまうのでこの動きではちょっと違いますね。

    キャンセル

0

結局やりたいことを最大限に汲み取った結果、以下のようになりました。

id は数字で始まる命名はできません。
http://www.tagindex.com/html_tag/attribute/id.html

sectionにつけていた連番のクラス名は削除しました。
たいていの場合、メンテナンス性を損ねるため。

<!doctype html>
<!--[if lt IE 7]> <html class="ie6 oldie"> <![endif]-->
<!--[if IE 7]>    <html class="ie7 oldie"> <![endif]-->
<!--[if IE 8]>    <html class="ie8 oldie"> <![endif]-->
<!--[if gt IE 8]><!-->
<html class="">
    <!--<![endif]-->
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Untitled Document</title>
        <style type="text/css">
            .current a {
                color:red;
            }
            section {
                height: 300px;
            }
        </style>
    </head>
    <body>
        <header>
            <nav>
                <ul class="navigation">
                    <li class="current"><a href="#top">1番</a></li>
                    <li><a href="/hoge/">2番</a></li>
                    <li><a href="#sec03">3番</a></li>
                    <li><a href="#sec04">4番</a></li>
                    <li><a href="#sec05">5番</a></li>
                    <li><a href="#sec06">6番</a></li>
                </ul>
            </nav>
        </header>
        <main>
            <article>
                <!-- bodyのidはこちらに移動 -->
                <section id="top">セクション01</section>
                <section>セクション02</section>
                <section id="sec03">3番</section>
                <section id="sec04">4番</section>
                <section id="sec05">5番</section>
                <section>セクション</section>
                <section>セクション</section>
                <section>セクション</section>
                <section id="sec06">6番</section>
                <section>セクション</section>
            </article>
        </main>
        <script
        src="//code.jquery.com/jquery-1.12.4.js"></script>
        <script>
            $(function () {
                $('.navigation a[href^="#"]').on('click', function () {
                    // 一旦currentを全部消す
                    var lists = $(this).parents('ul').children('li');
                    lists.removeClass('current');

                    // クリックしたa要素の親liにcurrentをつける
                    var li = $(this).parent('li');
                    li.addClass('current');

                    // スムーズスクロール
                    var href_val = $(this).attr('href');
                    var t = $(href_val).offset().top;
                    $('html,body').animate({
                        scrollTop: t
                    }, 800, 'swing');
                    return false;
                });
            });
        </script>
    </body>
</html>

 要件が足りなかったようなので修正

<!doctype html>
<!--[if lt IE 7]> <html class="ie6 oldie"> <![endif]-->
<!--[if IE 7]>    <html class="ie7 oldie"> <![endif]-->
<!--[if IE 8]>    <html class="ie8 oldie"> <![endif]-->
<!--[if gt IE 8]><!-->
<html class="">
    <!--<![endif]-->
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Untitled Document</title>
        <style type="text/css">
            .current a {
                color:red;
            }
            section {
                height: 300px;
            }
        </style>
    </head>
    <body>
        <header>
            <nav>
                <ul class="navigation">
                    <li class="current"><a href="#top">1番</a></li>
                    <li><a href="/hoge/">2番</a></li>
                    <li><a href="#sec03">3番</a></li>
                    <li><a href="#sec04">4番</a></li>
                    <li><a href="#sec05">5番</a></li>
                    <li><a href="#sec06">6番</a></li>
                </ul>
            </nav>
        </header>
        <main>
            <article>
                <!-- bodyのidはこちらに移動 -->
                <section class="col1" id="top">セクション01</section>
                <section class="col2">セクション02</section>
                <section class="col3" id="sec03">3番</section>
                <section class="col4" id="sec04">4番</section>
                <section class="col5" id="sec05">5番</section>
                <section class="col1">セクション</section>
                <section class="col2">セクション</section>
                <section class="col3">セクション</section>
                <section class="col4" id="sec06">6番</section>
                <section class="col5">セクション</section>
            </article>
        </main>
        <script
        src="//code.jquery.com/jquery-1.12.4.js"></script>
        <script>
            $(function () {

                function removeListClass() {
                    $('.navigation li.current').removeClass('current');
                }

                $('.navigation a[href^="#"]').on('click', function () {
                    // 一旦currentを全部消す
                    removeListClass();

                    // クリックしたa要素の親liにcurrentをつける
                    var li = $(this).parent('li');
                    li.addClass('current');

                    // スムーズスクロール
                    var href_val = $(this).attr('href');
                    var t = $(href_val).offset().top;
                    $('html,body').animate({
                        scrollTop: t
                    }, 800, 'swing');
                    return false;
                });

                function getElementByWindowTop(scrollTop) {
                    var anchors = $('.navigation a[href^="#"]');
                    var data = {};
                    anchors.each(function (i) {
                        var id = $(this).attr('href');
                        var t = $(id).offset().top;
                        data[id] = t;
                    });

                    var exitLoop = false;
                    $.each(data, function (id) {
                        if (exitLoop) {
                            return;
                        }
                        if (data[id] >= scrollTop) {
//                            console.log(id);
                            removeListClass();
                            $('.navigation li:has(a[href="' + id + '"])').addClass('current');
                            exitLoop = true;
                        }
                    });
                }

                // 変数宣言
                var timerId;

                // スクロール停止イベントのバインド
                $(window).bind("scrollFinish", function (event, scrollTop) {
                    // メニュー移動処理呼び出し(後に掲載するサンプルを参照して下さい)
                    getElementByWindowTop(scrollTop);
                });

                // スクロールイベントのバインド
                $(window).bind("scroll", function () {
                    var scrollTop = $(document).scrollTop();
                    if (timerId) {
                        clearTimeout(timerId);
                    }
                    // 1秒間スクロールしない場合はscrollFinishイベントを呼び出し
                    timerId = setTimeout(function () {
                        timerId = null;
                        $(window).trigger("scrollFinish", [scrollTop]);
                    }, 100);
                });

                $(window).unload(function () {
                    $(window).unbind("scroll scrollFinish");
                });
            });
        </script>
    </body>
</html>

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/12/15 23:05

    Kosuke_Shibuya様
    ご回答ありがとうございました。

    後出しで大変申し訳無いのですが、ナビゲーションを押下した場合にカレントをつける方法ではなく、どちらかと言うと、スクロールした場合にカレントをつける方法を希望していました。大変失礼しました。ですが、IDに数字で始まる命名はしていけないことを指摘していただきありがとうございました。
    プログラムを教えていただき、ありがとうございました。

    キャンセル

  • 2017/12/15 23:13

    > スクロールした場合にカレントをつける方法

    追記したコードがそのようになっています。どちらかというと、両方やる必要があるかと思いますが。

    キャンセル

  • 2017/12/15 23:22

    Kosuke_Shibuya様
    ご回答ありがとうございます。
    頂いたコードでやってみたのですが、うまく動作しなかったのですが、私がうまくできなかったのか、もう一度見直してみます。しばしお待ち下さい。

    キャンセル

  • 2017/12/15 23:27

    どうでしょう?検証が足りなかったでしょうかね?

    キャンセル

  • 2017/12/15 23:39

    Kosuke_Shibuya様
    やはりうまく動作しませんね。。。
    スクロールの.offset().topがずれているのか、早い段階でカレントが移動してしまいます。
    ヘッダーの高さ分よりもずれているので少し検証が必要かもです。。。
    もしかしたら私の書き方が間違っているかも??

    ↓頂いたサンプルコード↓
    https://codepen.io/sekis/pen/WdQNYG

    キャンセル

  • 2017/12/15 23:43

    CodePenでは htmからではなく、 body から書けと警告が出ていますね。

    キャンセル

  • 2017/12/15 23:47

    Kosuke_Shibuya様
    確かに警告がでてました。修正致しました。
    ローカル環境でも試したのですが、やはりずれてしまいますね。。。

    キャンセル

  • 2017/12/15 23:53 編集

    ずれているということですね。そこは調整必要ですね。
    ガチガチのチェックしているわけじゃないので、そこは調整してください。
    一応メンテナンス性考えて書いたつもりなので、HTMLが変わってもjsはいじらなくても良くなるはずです。

    キャンセル

  • 2017/12/16 00:01

    Kosuke_Shibuya様
    ご回答ありがとうございます。

    頂いたコードでも試してやってみます。メンテナンス性のことも考慮していただきありがとうございました。もう一度上から見直して頂いたコードを参考に綺麗に書いてみます。
    お手数をお掛けして、失礼しました。
    ありがとうございました。

    キャンセル

0

サンプルコード
https://jsfiddle.net/bdbLgabb/1/

とくに行数としては短くはなってないのですが、
ユーティリティ関数とセクションの位置情報を保持するクラスを追加しました。
管理するセクションを集め、スクロールイベント時に、
現在のスクロール座標が含まれているセクションを探し、
見つけたら該当するナビゲーションにクラスを付与するという流れになります。
どうでしょうか・・・

$(function(){
    const headerheight = $( 'header' ).outerHeight();
    $( 'main' ).css( 'padding-top', headerheight );

    $( 'a[href^="#"]' ).on( 'click', function (){
        const Href = $( this ).attr( "href" );
        const position = $( Href ).offset().top;
        $( 'body,html' ).animate( {
            scrollTop: position - headerheight
        }, 800, 'swing' );
        return false;
    } );

    // 主にここから↓↓↓↓を変更しました
    /** 範囲処理 */
    function range(a, b){
        return {
            /**
             * 指定範囲内に含まれているかチェック
             * @param {number} val
             */
            include: function(val){
                return a <= val && b > val;
            }
        }
    }

    class SectionItem {
        /**
         * sectionキーとtopとbottom座標を保持
         * @param {string} key 
         * @param {number} top 
         * @param {number} bottom 
         */
        constructor(key, top, bottom) {
            this.key = key;
            this.top = top;
            this.bottom = bottom;
        }
    }

    (function (){
        /**
         * 管理対象のセクションを収集
         * @type {SectionItem[]}
         */
        const items = $('section').map(function (i, elem){
            const $elem = $(elem);
            const id = $elem.attr('id');
            const top = $elem.offset().top;
            const bottom = top + $elem.height();
            //idがあるものだけ管理
            if( id ) return new SectionItem( id, top, bottom );
        }).toArray();

        const $navli = $('header nav ul li');
        const $win = $(window);

        /** スクロール時に処理する関数 (可能ならlodashを使って間引いたり) */
        const scrollProcess = function (){
            const y = $win.scrollTop() + headerheight;
            //いったん全部削除
            $navli.removeClass('current');
            //該当座標範囲内のセクションアイテムを探す
            const item = items.find( p => range( p.top, p.bottom ).include(y) );
            //あればcurrentクラスを付与
            if( item ) $(`a[href="#${item.key}"]`, $navli).parent().addClass('current');
        };

        $win.scroll(scrollProcess);

        //初回のみ手動実行
        scrollProcess();
    })();
});

htmlは<section class="col1" id="top">セクション01</section>だけ追加しました。
sectionのidを元にナビゲーションのcurrent操作をしているので、
本格的に利用する場合はもう一手間かけ、
管理用のプロパティを付与するなり、仕様変更を推奨します。

追記~仕様変更例~
仕様変更その1:bodyのid=topを削除
仕様変更その2:他と同じようにナビ側を<li><a href="#01">1番</a></li>として、セクションも
<section class="col1" id="01">セクション01</section>とする

/*~省略~*/
<body id="top">
    <header>
        <nav>
            <ul>
                <li><a href="#top">1番</a></li>
                <li><a href="/hoge/">2番</a></li>
                <li><a href="#03">3番</a></li>
                <li><a href="#04">4番</a></li>
                <li><a href="#05">5番</a></li>
                <li><a href="#06">6番</a></li>
            </ul>
        </nav>
    </header>
    <main>
        <article>
            <section class="col1" id="top">セクション01</section>
            <section class="col2">セクション02</section>
            <section class="col3" id="03">3番</section>
            <section class="col4" id="04">4番</section>
            <section class="col5" id="05">5番</section>
            <section class="col1">セクション</section>
            <section class="col2">セクション</section>
            <section class="col3">セクション</section>
            <section class="col4" id="06">6番</section>
            <section class="col5">セクション</section>
        </article>
    </main>
<script
  src="https://code.jquery.com/jquery-1.12.4.js"
  integrity="sha256-Qw82+bXyGq6MydymqBxNPYTaUXXq7c8v3CwiYwLLNXU="
  crossorigin="anonymous"></script> 
<script src="/js/main.js"></script> 
</body>
</html>

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/12/15 23:27

    so87様
    ご回答ありがとうございました。
    サンプルコードまで用意していただきありがとうございます。

    ちょっと直ぐに理解が出来ないので順を追って上からご返事させていただきます。しばしお待ち下さい。

    キャンセル

  • 2017/12/16 00:04

    コードをローカル環境で試した所、うまく動作しました。ありがとうございます。
    ただ、自分にとっていきなり難しいソースに感じてしまって理解するのに時間が掛かりそうです。。。

    大変勉強になりました。
    お手数をお掛けして失礼しました。

    キャンセル

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

ただいまの回答率

91.26%

関連した質問

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

  • JavaScript

    11747questions

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

  • HTML

    6429questions

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

  • jQuery

    5045questions

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

  • CSS

    4056questions

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