Javascript

Javascript30 - day22 : Follow Along Links

joy_lee 2021. 4. 23. 15:08

목표

link위에 마우스가 올라갔을 때, highlight가 마우스를 따라다니도록 한다.

사이트의 툴팁 메뉴ink위에 마우스가 올라갔을 때, highlight가 마우스를 따라다니도록 한다.

 

코드를 작성하기 전에

1
2
3
4
5
6
7
8
9
10
11
12
.highlight {
  transition: all 0.2s;
  border-bottom: 2px solid white;
  position: absolute;
  top: 0;
  background: white;
  left: 0;
  z-index: -1;
  border-radius: 20px;
  display: block;
  box-shadow: 0 0 10px rgba(0,0,0,0.2);
}
cs

highlight 클래스의 CSS를 미리 설정해둔다.

a와 border-radius를 같게 설정해 highlight가 적용됐을 때 어색하지 않도록 한다.

transition: all 0.2s; // highlight가 이동할 때 자연스럽게 움직이도록 설정함.

z-index: -1; // a 아래쪽에 위치해 글씨를 가리지 않도록 한다.

display: block; // width, height를 가질 수 있도록 block으로 설정해준다.

 

 

내가 작성한 코드

1
2
3
4
5
6
7
8
9
const links = document.querySelectorAll('a');
 
links.forEach(link => link.addEventListener('mouseover', e => {
  event.target.classList.add('highlight');
}));
 
links.forEach(link => link.addEventListener('mouseout', e => {
  event.target.classList.remove('highlight');
}));
cs

결과

목표했던 것처럼 하이라이트가 움직이지 않았다.

highlight가 움직이는 것이 아니라 마우스가 올라간 곳에 나타났다가 사라졌다

 

 

강의속 코드

1
2
3
4
const triggers = document.querySelectorAll('a');
const highlight = document.createElement('span');
highlight.classList.add('highlight');
document.body.append(highlight);
cs

highlight class를 가지는 span을 따로 만들어주었다.

highlight가 사라졌다가 나타나는 것이 아니고, 다른 링크에 마우스가 올라가기 전에는 이전 링크에 위치한다.

highlight가 이동하는 것 처럼 나타내기 위해서는 a에 class를 적용하는 것이 아니었다.

 

 

1
triggers.forEach(a => a.addEventListener('mouseenter', highlightLink));
cs

triggers 위에 마우스가 올라갈 때마다 highlightLink함수가 실행되도록 한다.

* mouseover/mouseout : 직접 이벤트를 걸지 않은 자식요소에 마우스 포인터가 와도 발생한다

* mouseenter/mouseleave : 오직 자기 자신에게 마우스 포인터가 와야만 발생한다

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
 function highlightLink() {
  // event가 일어난 객체가 this가 된다.
  const linkCoords = this.getBoundingClientRect();
  const coords = {
    width: linkCoords.width,
    height: linkCoords.height,
    top: linkCoords.top + window.scrollY,
    left: linkCoords.left + window.scrollX
  };
 
  highlight.style.width = `${coords.width}px`;
  highlight.style.height = `${coords.height}px`;
  highlight.style.transform = `translate(${coords.left}px, ${coords.top}px)`;
}
cs

a를 통해 발생한 event에 연결된 함수 highlight는 event가 일어난 객체를 this로 가진다.

this.getBoundingClientRect();로 얻어낸 DOMRect는 여러가지 위치에 대한 정보를 가진다.

 

* element.getBoundingClientRect();

webisfree.com/2020-09-21/[%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8]-%EC%97%98%EB%A6%AC%EB%A8%BC%ED%8A%B8%EC%9D%98-%ED%8E%98%EC%9D%B4%EC%A7%80-%EC%9C%84%EC%B9%98-%EC%95%8C%EC%95%84%EB%82%B4%EA%B8%B0-getboundingclientrect

 

[자바스크립트] 엘리먼트의 페이지 위치 알아내기, getBoundingClientRect

자바스크립트를 사용하여 화면으로부터 DOM 엘리먼트의 위치(position)를 알 수 있는 방법에 대하여 알아봅니다.

webisfree.com

위의 글을 참고해서 정리한 그림이다. <Contact Us> 위에 마우스를 올렸을 때 나타난 DOMRect이다.

getBoundingClientRect();로 얻어낸 DOMRect는 여러가지 위치에 대한 정보를 가진다.

 

우리가 원하는 정보는 highlight의 크기를 설정할 width, height와 위치를 설정할 top, left이다.

coords array에 정보들을 저장해 highlight.style과 style.transform로 쉽게 정보를 변경하도록 한다.

* top = linkCoords.top으로 설정하면 화면을 이동했을 때 highlight가 다른 위치에 가있게된다.

linkCoord.top 은 보이는 화면을 기준으로 측정한 거리이고,

실제 link의 위치는 페이지의 맨 위를 기준으로 하기 때문이다.

그래서 coords.top에는 window.scrollY를 더해줘야 link의 위치에 highlight가 자리할 수 있다.

 

 

새롭게 알게된 점

  • 오타를 조심할것! 코드는 잘 작성했는데 highlight 자체가 나타나지 않아서 확인해봤더니 hightlight 라고 작성한 것이 있었다.
  • 내가 생각한 방향이 목표와는 달랐다. 목표를 정확히 이해하고, 코딩을 시작해야 한다.
    (다른 link위에 마우스가 가기 전에 떠났던 link에 highlight가 남아있음을 생각하지 못함)
  • element.getBoundingClientRect(); // 쉽게 element의 위치를 알 수 있다.
  • width, height를 각각 선언해주는 것보다, 관련있는 정보들은 coords array에 같이 저장하는 것이 더 사용하기 편리한 것 같다.