웹사이트의 탭 메뉴를 클릭하면 특정 위치로 스크롤 바가 이동되면서 화면에 보여지는 작업
✍️ 원하는 요소로 스크롤 하는 동작을 이해한 과정대로 기록한 내용이다.
const navbarMenu = document.querySelector(".navbar__menu");
navbarMenu.addEventListener("click", (e) => {
console.log(e);
});
data-*
사용자 지정 데이터 특성을 이용, 데이터를 가져온다.const navbarMenu = document.querySelector(".navbar__menu");
navbarMenu.addEventListener("click", (e) => {
console.log(e.target);
});
const navbarMenu = document.querySelector(".navbar__menu");
navbarMenu.addEventListener("click", (e) => {
console.log(e.target.dataset);
});
const navbarMenu = document.querySelector(".navbar__menu");
navbarMenu.addEventListener("click", (e) => {
console.log(e.target.dataset.link);
});
const navbarMenu = document.querySelector(".navbar__menu");
navbarMenu.addEventListener("click", (e) => {
const link = e.target.dataset.link;
const scrollTo = document.querySelector(link);
scrollTo.scrollIntoView({ behavior: "smooth" });
});
const navbarMenu = document.querySelector(".navbar__menu");
navbarMenu.addEventListener("click", (e) => {
const link = e.target.dataset.link;
if (link == null) {
return;
}
const scrollTo = document.querySelector(link);
scrollTo.scrollIntoView({ behavior: "smooth" });
});
const navbarMenu = document.querySelector(".navbar__menu");
navbarMenu.addEventListener("click", (e) => {
const link = e.target.dataset.link;
console.log(link);
if (link == null) {
return;
}
const scrollTo = document.querySelector(link);
scrollTo.scrollIntoView({ behavior: "smooth" });
console.log(scrollTo);
});
const contactBtn = document.querySelector(".home__contact");
contactBtn.addEventListener("click", () => {
// console.log(e.target);
// contactBtnDataset = contactBtn.target;
const scrollTo = document.querySelector("#contact");
scrollTo.scrollIntoView({ behavior: "smooth", block: "start" });
});
const navbarMenu = document.querySelector(".navbar__menu");
navbarMenu.addEventListener("click", (e) => {
const link = e.target.dataset.link;
if (link == null) {
return;
}
scrollIntoView(link);
});
const contactBtn = document.querySelector(".home__contact");
contactBtn.addEventListener("click", () => {
scrollIntoView("#contact");
});
function scrollIntoView(selector) {
const scrollTo = document.querySelector(selector);
scrollTo.scrollIntoView({ behavior: "smooth" });
}
❗️ 문제점
작동은 잘 되지만, 네브바가 섹션의 컨테이너를 침범해서 각 섹션 요소의 상단과 맞지 않는다.🤔
▼ 넷바 메뉴가 콘텐츠 상단에서 넷바 메뉴 높이만큼 가려지는 문제 해결하기
📌 아래를 활용해서 해결해 보자
- scrollY
- HTMLElement.offsetRop
- window.scrollTo + ({top:scroll})
✍️ 문제점 파악 및 계획하기
1. window.scrollTo(지정위치로 스크롤) 을 사용해야 하는데 여기서 지정위치y값은 {top: ?? }로 줄 것이다.
2. ??를 정의해야 한다. 그냥 정의하면 위와 같은 문제가 반복될 것이다. 나는 계산된 값으로 정의하고 싶다.
2-1. HTMLElement.offsetTop로 계산할 수 있겠다.
offsetTop으로 해당 요소의 top 위치(마진 값까지 포함한다고 한다)를 가져온다.
쿼리셀렉터 를 통해서 원하는 dataset 명을 담는다. (단순히 이름을 넣은 dataset) 쿼리셀렉터로 인해서 선택된 html 요소들을 활용해서 offsetTop을 출력해본다.
const navbarMenu = document.querySelector(".navbar__menu");
navbarMenu.addEventListener("click", (e) => {
const link = e.target.dataset.link;
if (link == null) {
return;
}
const LinkName = document.querySelector(link);
const myScrollY = LinkName.offsetTop;
console.log(myScrollY);
// window.scrollTo({top: myScrollY})
});
const LinkName = document.querySelector(link);
const myScrollY = LinkName.offsetTop - navbarHeight;
console.log(myScrollY);
window.scrollTo
MDN 한국번역 페이지에는 이렇게만 설명되어 있어서 값을 적어 넣는데 이해가 되지 않았다.
그리고 같은 API 영문 사이트에는 이렇게 두가지를 제시한다.
아래 사용예를 보고 작성해본다. 계산된 식을 넣은 변수를 top값으로 지정했는데, 실행이 되는 걸로 보아서 변수가 들어가는 것도 실행된 다는 것을 알 수 있었다. 🧐
❓결과는
이렇게 하고 나니 섹션의 위치와 네브바하단이 정확히 일치 하지 않는다. 어떤 마진이나 다른 속성값 때문인 것 같다.
CSS에서 navbar 속성의 패딩이나 마진값을 확인 해 보았지만 달리 맞아 보이는 값이 안보여서 직접 맞는 값을 찾아 넣었다.
const LinkName = document.querySelector(link);
const myScrollY = LinkName.offsetTop - (navbarHeight - 16);
console.log(myScrollY);
const contactBtn = document.querySelector(".home__contact");
contactBtn.addEventListener("click", () => {
const LinkName = document.querySelector("#contact");
const myScrollY = LinkName.offsetTop - (navbarHeight - 16);
window.scrollTo({ top: myScrollY, behavior: "smooth" });
});
scrollToFunc
함수를 정의, 중복을 제거하자.const navbarMenu = document.querySelector(".navbar__menu");
navbarMenu.addEventListener("click", (e) => {
const link = e.target.dataset.link;
if (link == null) {
return;
}
scrollToFunc(link);
});
const contactBtn = document.querySelector(".home__contact");
contactBtn.addEventListener("click", () => {
scrollToFunc("#contact");
});
function scrollToFunc(selector) {
const LinkName = document.querySelector(selector);
const myScrollY = LinkName.offsetTop - (navbarHeight - 16);
window.scrollTo({ top: myScrollY, behavior: "smooth" });
}
첫 번째 방법과는 다르게 정확히 섹션의 상단과 맞도록 스크롤이 되었다. 😀
reference
MDN - Window.scrollY
MDN - Window.scrollTo()
MDN - HTMLElement.offsetTop
MDN - data-*
dream-coding