[Javascript 30] Day 16 - mousemove textshadow

이사감·2021년 3월 15일
0

Javascript 30

목록 보기
14/15
post-thumbnail

Day 16 - mousemove textshadow

Day 08에서도 mouseevent를 쓰며 offset X,Y 값을 다룬 적 있는데, 객체를 기준으로 마우스의 좌표를 출력하는 것이라고 간단하게만 정리했었다. 이후 Day 13에서 offset 뿐만 아니라 scroll까지 활용하며 offset 종류들을 정리해보았었다.

Day 16에서는 또 다시 offset과 마우스 이벤트를 함께 사용하는데, 이때 offset값에 대한 이슈? 처리?를 어떻게 하는지 강의 내용을 기반으로 정리해보았다.

요구사항

TIL

1. ES6 destructuring 구조 분해 할당

구조 분해 할당 구문은 배열이나 객체의 속성을 해체하여 그 값을 개별 변수에 담을 수 있게 하는 JavaScript 표현식입니다. MDN

  const hero = document.querySelector(".hero");
  const text = hero.querySelector("h1");

  function shadow(e) {
    const { offsetWidth: width, offsetHeight: height } = hero;
    // const width = hero.offsetWidth,
    //       height = hero.offsetHeight;
    // 와 같습니다.
    
    let { offsetX: x, offsetY: y } = e;
    // let x = e.offsetX,
    //     y = e.offsetY;
    // 와 같습니다.
  }

2. this와 e.target이 다를 때의 offset

  const hero = document.querySelector(".hero");
  const text = document.querySelector("h1");

  function init(e) {
    console.log(e.offsetX, e.target);
  }
  
  hero.addEventListener("mousemove", init);

화면 전체를 차지하는 div안에 h1이 있다. 마우스가 h1위에 위치하면 이때 offsetX의 값은 0부터 다시 시작한다. h1을 벗어나면 div를 기준으로 값이 측정됨을 볼 수 있다. 1, 0, -1, 62, 61, 60 순으로 값이 콘솔에 찍히는데 -1과 62 사이의 단절을 해결해야 한다. 일단 왜 이렇게 되는건지 궁금했다.

  const hero = document.querySelector(".hero");
  const text = document.querySelector("h1");

  function init(e) {
    console.log(e.offsetX, e.target, this);
  }
  
  hero.addEventListener("mousemove", init);

위와 같이 콘솔을 찍어 확인해보았는데, 직접 보면 알 수 있듯이 mousemove 이벤트가 발생할 때, 하늘색으로 밑줄친 this는 항상 컨테이너인 div였고 노란색으로 밑줄친 e.target은 컨테이너의 자손 요소였다. 마우스의 움직임에 따라 thise.target이 같지않아져 1, 0, -1, 62, 61과 같이 값이 연속적이지 않게 찍힌 것이다. 이를 다음과 같은 방법으로 해결할 수 있었다.

  const hero = document.querySelector(".hero");
  const text = document.querySelector("h1");

  function init(e) {
    const { offsetWidth: width, offsetHeight: height } = hero;
    let { offsetX: x, offsetY: y } = e; 
    if (this !== e.target) {
      x = x + e.target.offsetLeft;
      y = y + e.target.offsetTop;
    }
    console.log(e.offsetX, x, e.target, this);
  }
  hero.addEventListener("mousemove", init);

thise.target이 다를 때(=e.targeth1일 때), offsetXoffsetLeft(스크린샷 속의 빨간 선)를 더해주었다.

  • HTMLElement.offsetLeft
    요소의 left border 부터 offsetParent 의 left border 까지의 거리를 double 로 반환합니다.
  • HTMLElement.offsetParent
    모든 오프셋 계산이 현재 연산된 요소인 Element 를 반환합니다. MDN

마우스가 h1위에 있을 때 e.targeth1이고, h1의 좌측 border부터 offsetParentbody의 좌측 border까지의 거리를 offsetLeft로 나타낸다. 따라서 이 코드에서 offsetLeft의 값은 2가지이다.
(1) 0이거나 (e.target이 div인 경우) (2) 빨간 선만큼의 거리이거나 (e.target이 h1인 경우).

최종적으로 offsetXoffsetLeft를 더한 값은 스크린샷 속 콘솔에 찍힌 빨간색 밑줄 값처럼 나와, '1, 0, -1, 62, 61, 60'같이 불연속적이던 문제를 해결할 수 있다.

profile
https://emewjin.github.io

0개의 댓글