나 이제 DOM 앎

가은·2022년 8월 1일
0

Monet 갤러리

목록 보기
5/9

스크롤 애니메이션

sa 클래스를 가진 div 요소들이 스크롤 애니메이션의 대상이고 처음 sa 클래스를 통해 opacity:0 으로 보이지 않게 처리해준다.

보이지 않는 상태에서 사용자가 스크롤을 내리면

if (element.dataset.saTrigger) {
            saTriggerHeight = document.querySelector(element.dataset.saTrigger).getBoundingClientRect().top + saTriggerMargin;
        } else {
            saTriggerHeight = element.getBoundingClientRect().top + saTriggerMargin;
        }

코드 안에 getBoundingClientRect().top 이 작아지면서 해당요소에 show 클래스 추가 조건이 충족되어 opacity가 1이 되며 보인다.

.sa {
    opacity: 0;
    transition: all 3s ease;
}
.sa-up {
    transform: translate(0,150px);
}   /* 아래 > 위 */

.sa-right {
  transform: translate(-100px, 0);
}   /* 왼 > 오*/
.sa-left {
  transform: translate(100px, 0);
}   /* 오 > 왼 */
.sa.show {
    opacity: 1;
    transform: none;
}

처음 적용시켰을 때 클래스에 width 값이랑 height 값이 안정해져 있어서(이게 문제엿음) 계속 구역이 사라지길래 예제를 먼저 적용시키고 그걸 바탕으로 해보니까 되더랑

사진이랑 작가의 간단한 프로필은 문단들이랑 따로 애니메이션을 주고 싶어서 각자 div로 묶어주고 애니메이션을 각각한테 줬다. 그리고 사진이랑 프로필의 등장시간에 차이를 주고 싶어 클래스 옆에 data-sa-delay 속성으로 0.1초의 시간차이를 뒀다. (티가 안날 수 있지만 그냥 겉멋이라 생각하자)

saTriggerMargin 을 이용해서 위치에 의존하여 표시 타이밍을 임의적으로 조정할 수 있다. saTriggerMargin의 기본 값은 300이다. (const saDefaultMargin = 300;)

// Scroll
const saDefaultMargin = 300;
let saTriggerMargin = 0;
let saTriggerHeight = 0;
const saElementList = document.querySelectorAll('.sa');

const saFunc = function() {
for (const element of saElementList) {
    if (!element.classList.contains('show')) {
    if (element.dataset.saMargin) {
        saTriggerMargin = parseInt(element.dataset.saMargin);
    } else {
        saTriggerMargin = saDefaultMargin;
    }

    if (element.dataset.saTrigger) {
        saTriggerHeight = document.querySelector(element.dataset.saTrigger).getBoundingClientRect().top + saTriggerMargin;
    } else {
        saTriggerHeight = element.getBoundingClientRect().top + saTriggerMargin;
    }

    if (window.innerHeight > saTriggerHeight) {
        let delay = (element.dataset.saDelay) ? element.dataset.saDelay : 0;
         setTimeout(function() {
         element.classList.add('show');
         }, delay);
     }
     }
 }
 }

 window.addEventListener('load', saFunc);
 window.addEventListener('scroll', saFunc);

아무튼 내가 짠 코드는 아니고 대충 흐름은 읽히니 공부나 해보자

document.querySelectorAll

일단 querySelector()는 특정 name, id, class를 제한 하지 않고 css 선택자를 사용해서 요소를 찾는다. 같은 id 또는 class일 경우 스크립트의 최상단 요소만 로직에 들어온다.

querySelectorAll은 querySelector랑 사용법은 동일한데, 선택자를 선택해서 배열과 비슷한 객체인 nodeList를 반환한다. 반환객체가 nodeList라 for문이나 forEach문을 사용한다.

📍 nodeList가 뭐임?
일단 객체다. 일반적으로 element.childNodes와 같은 속성(property)과 document.querySelectorAll 와 같은 메서드에 의해 반환되는 노드 콜렉션이라 한다.
배열은 아닌데, forEach문을 사용해서 반복할 수 있고 Array.from()을 사용해서 배열로 변환될 수도 있다.
특히 document.querySelectorAll은 DOM을 변경해도 콜렉션 내용에는 영향을 주지 않는 정적 nodeList이다.
⚠️ for문을 사용하는 건 맞는데 리스트 항목을 열거하기 위해 for in문이나 for each in문은 사용하지 않는걸로 한다. 이 두개는 nodeList의 길이와 항목 속성까지 열거해서 오류가 생길 것이다. MDN에선 for of문을 사용하는 걸 권장한다.

element.classList.contains('class_name')

element.classList 는 엘리먼트의 클래스 속성의 콜렉션인 활성 DOMTokenList를 반환하는 읽기 전용 프로퍼티이다. classList의 사용은 공백으로 구분된 문자열인 element.calssName을 통해 엘리먼트의 클래스 목록으로 접근한다.
그 중 contains 메서드는 지정한 클래스 값이 앨리먼트의 class 속성에 존재하는지 확인한다.

element.dataset

element: 태그 요소 + dataset: 해당 html 태그의 data-* 속성의 키/값 모음 + keyname: 특정 data 키

html5부터 특정 DOM 요소에 사용자가 임의로 key나 value 형태로 특정 데이터를 저장한다. dataset 자체는 읽기 전용 속성이나 별도로 재설정은 불가하다. (변경하고 싶음 dataset 소속의 keyname에 접근해서 변경)'

getBoundingClientRect().top

getBoundingClientRect() 메서드는 엘리먼트의 크기와 뷰포트에 상대적인 위치 정보를 제공하는 DOMRect 객체를 반환한다. (쉽게 현재 보이는 화면을 기준으로 하는 좌표값을 준다.)

반환 값은 padding과 border-width를 포함해 전체 엘리먼트가 들어 있는 가장 작은 사각형인 DOMRect 객체이다. left, top, right, bottom, x, y, width, height 프로퍼티는 전반적인 사각형의 위치와 크기를 픽셀 단위로 나타낸다.

현재화면이 기준이기 때문에 스크롤 위치 등에 따라 값이 변한다. 그래서 동적으로 움직이는 좌표를 구할 때 나이스임

📍 DOMRect ? 직사각형의 크기와 위치를 나타냄

DOM도 제대로 모르면서 이걸 할라했어?

MDN 보는데 DOM 얘기가 계속 나와서 뭐냐 했더니,,, 자스 개념 공부할 때도 DOM 부분 있었는데 아 어려웡 하고 안본 기억이 스멀스멀 올라옴 진짜 ㅋㅋ 반성해라 이자시가...

문서 객체 모델(the Document Object Model)은 html, xml 문서의 프로그래밍 인터페이스이다.
DOM은 문서의 구조화된 표면을 제공하며 프로그래밍 언어가 DOM 구조에 접근할 수 있는 방법을 제공하여 그들이 문서 구조, 스타일, 내용 등을 변경할 수 있게 돕는다.

node와 objects로 문서를 표현하는데 이는 페이지를 스크립트 또는 프로그래밍 언어들에서 사용될 수 있게 연결시켜주는 역할을 담당한다.

DOM은 동일한 문서를 표현하고, 저장하고, 조작하는 방법을 제공한다. DOM은 웹 페이지의 객체 지향 표현이며, 자바스크립트와 같은 스크립팅 언어를 이용해 DOM을 수정한다.

DOM의 중요한 데이터 타입은 다음과 같다.
▪️ document
▪️ element
▪️ nodeList
▪️ attribute
▪️ namedNodeMap

그렇다고 DOM이 html이나 xml인 것은 절대 아니고 javascript인 것도 아니다악..!
그저 html 문서에 대한 인터페이스일 뿐

  • 뷰포트에 무엇을 렌더링 할지 결정하기 위해 사용
  • 페이지의 콘텐츠 및 구조, 자스에 의한 스타일 수정을 위해 사용

html 문서와 다른 건 무엇일까?

  • 항상 유효한 html 형식이다.
  • 자바스크립트에 수정될 수 있는 동적 모델이여야 한다.
  • 가상 요소를 포함하지 않는다. (::after ...)
  • 보이지 않는 요소를 포함한다. (display:none ...)

이쯤 하고 이제 프로필 부분 고치러 가야긋다 ㅎㅎ ㅂ2

profile
일이 재밌게 진행 되겠는걸?

0개의 댓글