프론트엔드/Tips

[자바스크립트] 스크롤 인디케이터 만들기

Marshall K 2019. 4. 16. 00:48

사용자가 글을 얼마나 읽었는지 표시해주는 막대를 화면에 첨부하는 방법입니다.

물론 옆에 있는 스크롤 바로도 알 수 있는 정보지만, 디자인도 훨씬 간단하게 수정이 가능할뿐더러, 이 페이지처럼 글에도 Infinite-scroll을 적용했다면 더더욱 필요한 기능입니다.


완성본

See the Pen Scroll Indicator by Marshall (@marshall-ku) on CodePen.


HTML

<div id="scroll_container"><div id="scroll"></div></div>


CSS

#scroll_container {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 3px
}

#scroll {
width: 100%;
height: 3px;
background: #000
}


Vanilla JS

function si() {
var a = document.body.scrollTop || document.documentElement.scrollTop,
b = document.documentElement.scrollHeight - document.documentElement.clientHeight;
document.getElementById("scroll").style.transform = `translateX(${100 * (a / b) - 100}%)`
}

si(),
document.addEventListener("scroll", si)


jQuery

function si() {
var a = $(window).scrollTop(),
b = $(document).outerHeight() - $(window).height();
$("#scroll").css("transform", `translateX(${100 * (a / b) - 100}%)`)
}

si(),
$(window).on("scroll", si)


스크롤 진행률 구하기

a는 body가 스크롤 된 길이(px) 혹은 html이 스크롤 된 길이를 가져옵니다.

b는 html의 총 높이에서 뷰포트의 높이를 뺀 값입니다.


예를 들어, 보라색 박스가 사용자의 모니터 크기고, 사진 전체가 웹페이지라 가정합시다.


당연히 스크롤을 맨 마지막까지 끌어내려도 사용자는 html의 높이만큼 스크롤 할 수 없습니다.

이렇게요.

그러니 뷰포트의 높이만큼 빼줘야 정상적으로 작동합니다.


ScrollTop 관련 글

ScrollHeight 관련 글

ClientHeight 관련 글


인디케이터에 적용하기

솔직히 성능이야 기기들의 상향 평준화가 심해 width를 쓰나 transform을 쓰나 체감되는 차이는 거의 없습니다만, 성능 향상을 위해 transform을 사용해 인디케이터를 뷰포트 밖에 보내서 천천히 뷰포트 안으로 끌고 들어오는 방식을 사용했습니다.


굳이 width를 사용하고 싶으시면

document.getElementById("scroll").style.width = 100 * (b / f) + "%"

이렇게 작성하시면 됩니다.


퍼센티지 추가하기


HTML

<div id="scroll_container"><div id="scroll"><div id="percent"></div></div></div>

#percent를 새로 추가했습니다.


Vanilla JS

function si() {
var a = document.body.scrollTop || document.documentElement.scrollTop,
b = document.documentElement.scrollHeight - document.documentElement.clientHeight,
c = 100 * (a / b);
document.getElementById("scroll").style.transform = `translateX(${c - 100}%)`,
document.getElementById("percent").innerText = `${Math.floor(c)}%`
}


jQuery

function si() {
var a = $(window).scrollTop(),
b = $(document).outerHeight() - $(window).height(),
c = 100 * (a / b);
$("#scroll").css("transform", `translateX(${c - 100}%)`),
$("#percent").text(`${Math.floor(c)}%`)
}


스크롤 진행률이 두 군데에 쓰이게 됐으니, 변수로 지정해줍니다.


개발자도구로 스크롤 하시며 translateX 값을 보시면 아시겠지만, 어마 무시한 소수점이 반겨주므로, Math.floor를 통해 소수점은 버려주고, 그 값을 #percent 안에 넣어줍니다.


CSS

#percent {
display: inline-block;
position: absolute;
right: 0;
top: 5px;
color: #aaa;
background: #fff;
}

간단한 css도 추가해줍니다.


부드럽게 이동시키기


transition: transform 0.5s cubic-bezier(0, 0, 0.55, 1);

#scroll에 transition을 주면 요소를 부드럽게 이동시킬 수 있습니다.