Intersection Observerの使い方　ー まとめ ー

# はじめに
スクロールを行った際、画面内に対象物が入った時にJavaScriptを実行するという処理を学習したため、まとめたいと思います。

# もくじ
1. Intersection Observerとは
2. 基本的な記述
3. options
4. おわり


# 1. Intersection Observerとは

Intersection Observerをそれぞれ日本語にすると、以下のように訳されます。

|<b>Intersection</b>|交差、交差点|
|-------------------|---------|
|<b>Observer</b>| <b>監視する者、観察者</b>|

このことから、Intersection Observerは<b>「（物体の）交差を監視する者」</b>という意味になります。


<b>「物体の交差」</b>とは、配置されている物体がスクロールされることで画面内（window内）に入ったり、出たりすることを「物体の交差」と表現されます。

そして、Intersection Observerはこの交差を監視しています。

# 2. 基本的な使い方
まずは、以下のようにnew IntersectionObserverへcallback関数を渡してあげ、それを変数io（Intersection Observerの略）とします。

```javascript
const io = new IntersectionObserver(callback);
```
<br>
次に、どのDOMを監視するのか、監視対象のDOMを登録します。

```javascript
const io = new IntersectionObserver(callback);

const item = document.querySelector('.item');
io.observe(item);
```
監視対象のDOMを登録するには、querySelectorで要素を取ってきて、それを変数に格納する。
と言う流れです。
上記のコードでは、class="item"がふられている要素を監視対象としたいため、classの要素をquerySelectorで取ってきて、それをitemという変数に格納しています。

そして、`io.observe(item);`とすることで、itemを監視対象に登録します。


こうすることで、登録されたitemが画面内に入ったり/画面外に出たりする時に、IntersectionObserverがそれを監視し、その度にcallback関数が呼び出されます。


### 画面内に入った時、出た時の定義方法

callbackの中身を記述していきます。

```javascript

// const item = document.querySelector('.item');

const callback = function(entries, observer) {
  entries.forEach(entry => {
    if(entry.isIntersecting) {
      entry.target.classList.add('inview');
    } else {
      entry.target.classList.remove('inview');
    }
  });
}

// const io = new IntersectionObserver(callback);
// io.observe(item);
```

まず、`entries.foreach`でどの要素が入ったのか/出たのかを確認。
そして、foreachの引数を`entry`とします。
このentryの中に、それぞれの要素（今回ではitemが）が含まれています。

<br>
条件分岐のところでは、`entry.isIntersecting`がtrueの場合、つまり今回の場合では画面内にitemが入ればclass="inview"を追加(add)、falseであればclass="inview"を削除(remove)するという記述になります。

```javascript:条件分岐
if(entry.isIntersecting) {
      entry.target.classList.add('inview');
    } else {
      entry.target.classList.remove('inview');
    }
```

`entry.target.classList.add('inview');`の`target`に、監視対象のDOMが格納されています。
そして、trueの場合そのDOMに対してclassの付与を行なっています(falseの場合はcalssを削除)。

***

<b>監視対象が画面内に入った時点で監視を終えたい</b>場合は、`observer.unobserve(entry.target);`と記述することで、監視を終了することができます。


```javascript

const item = document.querySelector('.item');

const callback = function(entries, observer) {
  entries.forEach(entry => {
    if(entry.isIntersecting) {
      entry.target.classList.add('inview');

      observer.unobserve(entry.target); // ← 画面内に入ったタイミングで監視を終了

    } else {
      entry.target.classList.remove('inview');
    }
  });
}

const io = new IntersectionObserver(callback);
io.observe(item);
```

***

# 3. options
Intersection Observerは第二引数にoptionsを取ることができます。
こんな感じ。

```javascript
const io = new IntersectionObserver(callback, options);
```
<br>
optionsの定義は以下のように記述します。

```javascript
const options = {
    root: null,
    rootMargin: "-100px 0px 0px 0px", // 上 右 下 左
    threshold: [0, 0.5, 1]
};
```
主なプロパティです。

|プロパティ|設定内容|
|-------------------|---------|
|<b>root</b>| 交差対象としたい親要素の設定（基本的には現在表示されている画面で設定） |
|<b>rootMargin</b>| デフォルト値は0px。 上記の設定では、画面の内側から見て上から100pxたったところが交差対象となる(pxが正の数字であれば外側)。<br><font color="tomato"><b>px をつけないとエラーになるので注意!</b></font>|
|<b>threshold</b>| デフォルト値は0。<br>threshold:１と設定すると、監視対象が画面内に全て入るまでは交差していないとみなされる。<br>配列で値を取ることもできる。|

![スライド1 (7).JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1379469/535a4dd7-8d26-5125-707d-9820fbbe8f09.jpeg)


![スライド2 (6).JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1379469/45f53dd8-005e-dddc-d6c8-cae7a6a0b926.jpeg)


# 4. おわり
スクロールするたびに画像がぽんぽん出てくるサイトの裏側はこういう風になってるのかな。
Intersection Observer、上手に使いこなせるようになるぞ！