ページ内リンクによるスムーズスクロール（jQuery利用）

# ページ内リンクによるスムーズスクロール
お世話になっております。コウヤです。

今日はページ内リンクをクリックして、スムーズにページ内を移動する方法について記載していきたいと思います。

以下のリンク（青背景箇所）をクリックすると、特段何も設定しない状態ではそのまま瞬間移動してその個所に飛ぶようになっていますが、これだとどの位置にいるかわかりづらくなってしまいます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602679/9d497424-4bfb-f7e9-4e59-1f66d44aeef6.png)


この状態から、リンクをクリックしたらページ内をスムーズにスクロールして、該当の位置に遷移できるように設定していきたいと思います。

リンクをクリックすると、ページ内を遷移しながら
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602679/9d497424-4bfb-f7e9-4e59-1f66d44aeef6.png)
↓

該当の位置にスクロールしながら移動する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602679/89d31c34-cdbb-e228-7479-8960980e87c9.png)

## HTML/CSSの設定について
今回のフォルダ構成は以下のとおりです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602679/9b8bddc4-6f6d-2ed8-5117-8456e947c623.png)


まずはHTML/CSSの設定を行います。
HTMLについてはBODYタグ内に以下のコードを入力します。

```html:index.html

    <header class="_bgc2">
      <ul class="nav__menu">
        <li class="nav__menu_item"><a href="#L1">リンク1</a></li>
        <li class="nav__menu_item"><a href="#L2">リンク2</a></li>
        <li class="nav__menu_item"><a href="#L3">リンク3</a></li>
        <li class="nav__menu_item"><a href="#L4">リンク4</a></li>
        <li class="nav__menu_item"><a href="#L5">リンク5</a></li>
        <li class="nav__menu_item"><a href="#L6">リンク6</a></li>
      </ul>
    </header>


    <main id="L1">
      <h1 class="L__title">リンク1</h1>
    </main>

    <main id="L2" class="_bgc">
      <h1 class="L__title">リンク2</h1>
    </main>

    <main id="L3">
      <h1 class="L__title">リンク3</h1>   
    </main>

    <main id="L4" class="_bgc">
      <h1 class="L__title">リンク4</h1>   
    </main>

    <main id="L5">
      <h1 class="L__title">リンク5</h1>
    </main>

    <main id="L6" class="_bgc">
      <h1 class="L__title">リンク6</h1>
    </main>

```

```css:style.css
@charset "UTF-8";
/*ベース
*********************/
body {
  color: #357a38;
  font-family: "Noto Sans JP", sans-serif;
}

a {
  text-decoration: none;
  color: #357a38;
}

._bgc {
  height: auto;
  background: #dbebc4;
}
._bgc2{
  height: auto;
  background: #dbebff;
}

header{
  padding:20px;
}

.nav__menu{
  display: flex;
  flex-direction: row;
  justify-content:space-around;
}



.nav__menu_item a{
  font-weight: 700;

}
#L1 {
  height: auto;
  padding-top: 45px;
  padding-bottom: 300px;
}
#L2 {
  height: auto;
  padding-top: 45px;
  padding-bottom: 300px;
}

#L3 {
  height: auto;
  padding-top: 45px;
  padding-bottom: 300px;
}
#L4 {
  height: auto;
  padding-top: 45px;
  padding-bottom: 300px;
}
#L5 {
  height: auto;
  padding-top: 45px;
  padding-bottom: 300px;
}
#L6 {
  height: auto;
  padding-top: 45px;
  padding-bottom: 300px;
}

.L__title {
  text-align: center;
  font-size: 32px;
  font-weight: 700;
}

```

すると、上記画像のように表示されると思いますが、現状この状態ではリンクをクリックしてもページ内スムーズスクロール状態ではありません。リンクをクリックすると瞬間移動してしまいます。

これを解消するのに、jQueryを記載していきたいと思います。

## jQueryの記載

まずは、リンクをクリックした際の処理を記載していきます。

```.js
/*jQueryエリア*/
$(function(){

	$('a[href^=#]:not([href=#])').click(function(){
		//ここに遷移する処理を記載
	});

});
```

**a[href^=#]:not([href=#])** について見ていきたいと思います。
今回はページ内のリンクは以下の箇所
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602679/27def582-24f9-a771-e670-726a4b69f94b.png)
しかないですが、実際にはいくつもあります。上記のリンクはいずれも
```.html
        <li class="nav__menu_item"><a href="#L1">リンク1</a></li>
        <li class="nav__menu_item"><a href="#L2">リンク2</a></li>
        <li class="nav__menu_item"><a href="#L3">リンク3</a></li>
        <li class="nav__menu_item"><a href="#L4">リンク4</a></li>
        <li class="nav__menu_item"><a href="#L5">リンク5</a></li>
        <li class="nav__menu_item"><a href="#L6">リンク6</a></li>
```
で、すべてhref属性は **\#L1** のように\#で始まってます。そのため、 **a[href^=#]** では\#で始まるものに対してという意味になるので、この時点で他の外部リンク等へのアクセスは無視されるのです。

また、\#だけのリンクについては、 **:not([href=#])** で除いております。つまり、以下のリンクも無視されます。
```
<a href="#"></a>
```

## 遷移先の位置の調査
jQueryで処理内容を記載していくのですが、遷移先の位置を把握する必要があります。
そのために、以下の処理内容を記載します。

```.js
/*jQueryエリア*/
$(function(){

	$('a[href^=#]:not([href=#])').click(function(){
		let target = $($(this).attr('href')).offset().top;
		console.log('縦の位置：' + target);
	});

});

```

ここでは、 **target** という変数を指定しています。
**$(this).attr('href')** ではクリックしたhrefで指定したものが入ると考えてください。例えば、下記で **\#L2** の箇所をクリックしたら、href属性（属性は英語でattribute）の値 **\#L2** が指定されます。

```.html
    <header class="_bgc2">
      <ul class="nav__menu">
        <li class="nav__menu_item"><a href="#L1">リンク1</a></li>
        <li class="nav__menu_item"><a href="#L2">リンク2</a></li>
        <li class="nav__menu_item"><a href="#L3">リンク3</a></li>
        <li class="nav__menu_item"><a href="#L4">リンク4</a></li>
        <li class="nav__menu_item"><a href="#L5">リンク5</a></li>
        <li class="nav__menu_item"><a href="#L6">リンク6</a></li>
      </ul>
    </header>


    <main id="L1">
      <h1 class="L__title">リンク1</h1>
    </main>

    <main id="L2" class="_bgc">
      <h1 class="L__title">リンク2</h1>
    </main>
```

その **L2** は今、上記のHTMLコードの **id="L2"** で指定されています。この「リンク2」のトップからの位置を **.offset().top** で取得しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602679/ae285c9c-c5ba-b07c-fa2b-207755a19420.png)

その位置情報を **target** に代入しています。実際に取得できているかを確認します。
Chromeを開いた状態で、キーボードの **F12** をクリックし、以下の赤枠のコンソールの箇所をクリックしてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602679/87698a0a-7f60-e4b9-bfa2-c274983ed89d.png)

その状態で「リンク2」をクリックすると、以下のようにトップからの位置情報がコンソールに出てきます。
console.log()で表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602679/5b95285a-8c46-fd6c-c88d-331bb09ab6cb.png)
↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602679/660a8865-2742-17e2-b87b-333b359bebe5.png)

この **target** 変数に今、位置情報の値が入っているということを念頭に置いてください。

## スムーズスクロールの実装
それではスムーズスクロールの実装をしていきます。

```.js
$(function(){

	$('a[href^=#]:not([href=#])').click(function(){
		let target = $($(this).attr('href')).offset().top;
		//console.log('縦の位置：' + target);
		$('html,body').animate({scrollTop : target}, 1000);
	});

});
```

なお、上記の
```
console.log('縦の位置：' + target);
```
は消しても問題ありません。

まず、セレクタとして、 **$('html,body')** に対して、 **.animate** メソッドででスクロールするようにします。
本来は、.animateメソッド内にはCSSを指定して、どのように変化させたいかをCSSで記載しますが、scrollTopプロパティがあるため、これでスクロール位置を指定します。

スクロール位置については、先程の **target** 変数に代入されているので、そこに1000msの時間をかけてページ内スクロールするように記載します。時間についてはミリ秒で自由に指定が可能です。

これで、ページ内リンクによるスムーズスクロールが可能となります。

## コードまとめ
```.html

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="robots" content="noindex">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="css/reset.css">
    <link rel="stylesheet" href="css/style.css">
    <script src="js/jquery-2.1.4.min.js"></script> 
    <script src="js/script_jQ.js"></script>

    <title>ページ内リンクとスムーズスクロール</title>

</head>
<body>


    <header class="_bgc2">
      <ul class="nav__menu">
        <li class="nav__menu_item"><a href="#L1">リンク1</a></li>
        <li class="nav__menu_item"><a href="#L2">リンク2</a></li>
        <li class="nav__menu_item"><a href="#L3">リンク3</a></li>
        <li class="nav__menu_item"><a href="#L4">リンク4</a></li>
        <li class="nav__menu_item"><a href="#L5">リンク5</a></li>
        <li class="nav__menu_item"><a href="#L6">リンク6</a></li>
      </ul>
    </header>


    <main id="L1">
      <h1 class="L__title">リンク1</h1>
    </main>

    <main id="L2" class="_bgc">
      <h1 class="L__title">リンク2</h1>
    </main>

    <main id="L3">
      <h1 class="L__title">リンク3</h1>   
    </main>

    <main id="L4" class="_bgc">
      <h1 class="L__title">リンク4</h1>   
    </main>

    <main id="L5">
      <h1 class="L__title">リンク5</h1>
    </main>

    <main id="L6" class="_bgc">
      <h1 class="L__title">リンク6</h1>
    </main>

    
  </body>
</html>
```

```.css
@charset "UTF-8";
/*ベース
*********************/
body {
  color: #357a38;
  font-family: "Noto Sans JP", sans-serif;
}

a {
  text-decoration: none;
  color: #357a38;
}

._bgc {
  height: auto;
  background: #dbebc4;
}
._bgc2{
  height: auto;
  background: #dbebff;
}

header{
  padding:20px;
}

.nav__menu{
  display: flex;
  flex-direction: row;
  justify-content:space-around;
}



.nav__menu_item a{
  font-weight: 700;

}
#L1 {
  height: auto;
  padding-top: 45px;
  padding-bottom: 300px;
}
#L2 {
  height: auto;
  padding-top: 45px;
  padding-bottom: 300px;
}

#L3 {
  height: auto;
  padding-top: 45px;
  padding-bottom: 300px;
}
#L4 {
  height: auto;
  padding-top: 45px;
  padding-bottom: 300px;
}
#L5 {
  height: auto;
  padding-top: 45px;
  padding-bottom: 300px;
}
#L6 {
  height: auto;
  padding-top: 45px;
  padding-bottom: 300px;
}

.L__title {
  text-align: center;
  font-size: 32px;
  font-weight: 700;
}

```

```.js
$(function(){

	$('a[href^=#]:not([href=#])').click(function(){
		let target = $($(this).attr('href')).offset().top;
		console.log('縦の位置：' + target);
		$('html,body').animate({scrollTop : target}, 1000);
	});

});
```