Project/I'm Hear

[트러블슈팅, JS] - ⭐스크롤을 항상 아래로⭐

조 수빈 2022. 9. 12. 23:56

22.09.07 기록
에러는 아니지만 새로 알게 된 내용이라 정리

⭐스크롤을 항상 하단으로 보내기⭐
(새로운 채팅 내용이 있으면 그 내용을 보여주기 위함)

결론: scrollTop, scrollHeight를 활용


📽 결과 화면

ok


✅ 해결 과정

채팅창에 스크롤 기능이 추가되었고, 요소들도 안에 잘 보이지만..
입력을 하면 밑에 내용이 추가되는데, 내가 스크롤 바를 내려야만 볼 수 있다.
스크롤바를 자동으로 항상 아래에 위치 시키고 싶었다.

그렇게 하기 위해서는 CSS 박스 모델의 요소들을 알 필요가 있어 보였다.
CSS 박스 모델에는 스크롤과 관련된 여러 요소들이 있으며, 자세한 것은 아래 사진들을 참고하자 출처는 stack overflow

자료마다 scrollHeight와 offsetHeight 등을 저마다 다르게 표기해놔서 헷갈렸다.
특히 개인 블로그의 이미지들은 정말 제각각인 경우도 있었다..
(아래 내용 중 틀린 부분이 있다면 피드백 부탁드립니다.)

여러 자료들을 참고한 결과, 스크롤바를 하단에 고정하기 위해 필요한 값이 2개(scrollTop, scrollHeight) 임을 알게 되었다.

scrollTop은 스크롤 바의 최상단 위치 값이다. 즉, 스크롤을 아직 내리지 않았다면 0이다.
이 페이지에서 실습해 볼 수 있다. 스크롤을 내리게 되면 그에 따라 위치 값이 증가하는 것을 확인할 수 있다.

다음은 scrollHeight, 이 값은 스크롤 기능으로 숨겨진 부분까지 모두 포함한 길이의 값이라고 할 수 있다. 따라서 채팅의 내용이 추가될수록 값이 증가한다.

(실제 진행 중인 프로젝트에서 해당 값들을 체크해 보았다.)

이 2개의 값을 통해 스크롤을 자동으로 내려주는 함수를 구현해 보았다.
위에서 언급했듯이, 스크롤이 내려가지 않은 상태의 scrollTop 값은 0이며, 스크롤이 내려갈수록 값은 증가한다.
즉, scrollTop 값을 증가시켜주면 현 스크롤의 위치도 하단으로 내려줄 수 있다.

그 증가 값으로는 scrollHeight를 사용했다. scrollHeight 값은 채팅방 내용의 전체 길이를 의미하므로, scrollTop에 scrollHeight 값을 더해준다면 채팅창의 스크롤을 아래로 내려줄 수 있다.

채팅창에 내용을 입력할 때마다 위의 과정이 일어나야 하므로, submit 이벤트가 일어날 때마다 scrollTop 값을 scrollHeight로 할당해 주는 함수를 실행시켰고, 그 결과 스크롤이 아래로 내려갔다!

하지만..
뭔가 이상했는데 알고 보니 가장 마지막 채팅 전까지만 내려오는 것이었다.
log를 찍어 확인해보니, submit 이벤트가 일어나자마자 함수를 실행시키니 가장 마지막에 추가된 채팅(li 요소)을 반영되지 않은 상태로 scrollHeight 값이 할당되었다.
✅ 따라서 준비 함수를 따로 선언해 주어 해결하였다.

// 채팅창 form(박스), submit 이벤트 감지를 위해 변수 선언
let chatForm = document.querySelector('.chat_form');

// 준비 함수, 약간의 시간을 두어 scroll 함수를 호출하기
function prepareScroll() {
  window.setTimeout(scrollUl, 50);
}

// scroll 함수
function scrollUl() {
  // 채팅창 form 안의 ul 요소, (ul 요소 안에 채팅 내용들이 li 요소로 입력된다.)
  let chatUl = document.querySelector('.chat_ul');
  chatUl.scrollTop = chatUl.scrollHeight; // 스크롤의 위치를 최하단으로
}

// submit 이벤트 감지
chatForm.addEventListener('submit', prepareScroll);