> For the complete documentation index, see [llms.txt](https://shhn0509.gitbook.io/make-better-netflix-website/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://shhn0509.gitbook.io/make-better-netflix-website/interaction/javascript/detect-scroll-position.md).

# Detect Scroll Position

## 문제  &#x20;

Header를 `position:fixed`로 바꾸고 나서 스크롤(Scroll)의 위치를 바꿨을 때 배경이미지 때문에 로고가 정확하게 보이지 않는 현상을 해결하기 위해 만들었다.&#x20;

![배경이미지 때문에 로고가 선명하게 보이지 않는다.](/files/-MQQpcDOh9PhXByQ6Srt)

## 목적 &#x20;

화면의 스크롤을 내렸을 때 미리 설정 해둔 배경 속성을 적용될 수 있도록 상태 클래스(`.scrolling--show`) 추가/제거 될 수 있도록 한다.

![상태클래스를 추가하면서 배경이 어둡게 변한다. ](/files/-MQQt793HpUOUllstdDp)

## 설계

### 변수 설정

```javascript
const SCROLL_SHOW_STATE_CLASSMNAME = 'scrolling--show'
const fixedHeaderNode = document.querySelector('.header--fixed')
```

### 방법&#x20;

1. `window.scrollY`를 사용해서 어느 위치에서 인터랙션을 적용할지 계산한다.
2. window에 'scroll' 이벤트를 바인딩한다.
3. &#x20;(1)에서 설정한 scrollY 값 이상일 경우 상태클래스 `.scrolling--show`가 추가/제거 될 수 있도록 `toggle()` 메서드를 사용한다.&#x20;

## 처음에 작성한 코드&#x20;

```javascript
const SCROLL_SHOW_STATE_CLASSMNAME = 'scrolling--show'
const fixedHeaderNode = document.querySelector('.header--fixed')

const scrollShowHide = function (target, Ypos = 0) {
  if (window.scrollY >= Ypos) {
    target.classList.toggle(SCROLL_SHOW_STATE_CLASSMNAME)
  }
}

const handleScrollShowHide = function () {
  scrollShowHide(fixedHeaderNode, 30)
}

window.addEventListener('scroll', handleScrollShowHide)
```

## 문제점 발견

{% embed url="<https://www.youtube.com/watch?v=ic5ZAqXBwNE>" %}

### 문제

toggle() 메서드는 추가/제거를 하는 기능을 하기 때문에 해당 코드에서는 scroll을 할 때마다 toggle이 된다. 그렇기 때문에 위와 같은 현상이 나타났다.

### 해결

#### add()/remove() 사용하기 &#x20;

```javascript
const scrollShowHide = function (target, Ypos = 0) {
  if (window.scrollY > Ypos) {
    target.classList.add(SCROLL_SHOW_STATE_CLASSMNAME)
  } else {
    target.classList.remove(SCROLL_SHOW_STATE_CLASSMNAME)
  }
}
```

## 개선&#x20;

* show와 hide 두 가지 기능이 있는 함수가 아닌 재사용이 가능한 함수로 만들기 위해 show, hide 각각의 기능을 가진 함수를 독립적으로 만들어서 재사용할 수 있도록 했다.&#x20;
* 함수 매개 변수에 `className`을 전달할 수 있도록 해서 `SCROLL_SHOW_STATE_CLASSNAME`을 두 번 사용하지 않도록 했다.&#x20;
* 조건에 `contains()`을 추가해서 함수가 한 번만 실행될 수있도록 했다. (성능 고려)&#x20;

```javascript
const SCROLL_SHOW_STATE_CLASSMNAME = 'scrolling--show'
const fixedHeaderNode = document.querySelector('.header--fixed')

var scrollShow = function (target, Ypos = 0, className) {
  if (window.scrollY >= Ypos && !target.classList.contains(className)) {
    target.classList.add(className)
  }
}

const scrollHide = function (target, Ypos = 0, className) {
  if (window.scrollY < Ypos && target.classList.contains(className)) {
    target.classList.remove(className)
  }
}

const handleScrollShowHide = function () {
  scrollShow(fixedHeaderNode, 30, SCROLL_SHOW_STATE_CLASSNAME)
  scrollHide(fixedHeaderNode, 30, SCROLL_SHOW_STATE_CLASSNAME)
}

window.addEventListener('scroll', handleScrollShowHide)

```
