Intersection Observer API의 JavaScript 빌드를 사용한 스크롤 애니메이션(타사 라이브러리 없음)
이 튜토리얼에서는 새로운 내장 웹 애니메이션 API를 사용하여 웹 사이트에서 페이지 섹션(이 경우 카드)에 애니메이션을 적용하는 방법에 대해 설명합니다. 추가 패키지는 필요하지 않습니다.
- 교차 관찰자 API란?
- Intersection Observer API 브라우저 지원
- 코딩하자
- 수평 지연 애니메이션
- 완전한 프로젝트 소스 코드
Intersection Observer API는 대상 요소와 상위 요소 또는 최상위 문서의 뷰포트가 교차하는 변경 사항을 비동기식으로 관찰하는 방법을 제공합니다.
역사적으로 요소의 가시성 또는 서로 관련된 두 요소의 상대적 가시성을 감지하는 것은 솔루션이 신뢰할 수 없고 사용자가 액세스하는 브라우저와 사이트를 느리게 만드는 경향이 있는 어려운 작업이었습니다. 웹이 성숙해짐에 따라 이러한 종류의 정보에 대한 필요성도 커졌습니다. 교차점 정보는 다음과 같은 여러 가지 이유로 필요합니다.
페이지가 스크롤될 때 이미지 또는 기타 콘텐츠가 지연 로드됩니다.
사용자가 페이지를 넘길 필요가 없도록 스크롤할 때 점점 더 많은 콘텐츠가 로드되고 렌더링되는 "무한 스크롤" 웹 사이트를 구현합니다.
광고 수익을 계산하기 위해 광고의 가시성을 보고합니다.
사용자가 결과를 볼 수 있는지 여부에 따라 작업 또는 애니메이션 프로세스를 수행할지 여부를 결정합니다.
자세한 내용은:https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API
2. Intersection Observer API 브라우저 지원
보시다시피 Intersection Observer API는 모든 주요 브라우저에서 지원됩니다.
3. 코딩하자
우리는 여기서 무엇을 만들고 있습니까?
코딩을 시작하자
다음과 같이 Intersection Oberrver API를 호출할 수 있습니다.
const observer = new IntersectionObserver(callback, options);
다음 상황 중 하나가 발생하면 콜백이 호출됩니다.
대상 요소 는 장치의 뷰포트 또는 지정된 요소와 교차합니다. 지정된 요소는 Intersection Observer API의 목적을 위해 루트 요소 또는 루트 라고 합니다.
관찰자가 처음에 대상 요소를 보도록 요청받은 첫 번째 시간입니다.
- 옵션 개체
root
대상의 가시성을 확인하기 위한 뷰포트로 사용되는 요소입니다. 대상의 조상이어야 합니다. 지정되지 않았거나 인 경우 브라우저 뷰포트가 기본값 null입니다.
rootMargin
루트 주위에 여백을 둡니다. margin예를 들어 "(상단, 오른쪽, 하단, 왼쪽)와 같은 CSS 속성 과 유사한 값을 가질 10px 20px 30px 40px"수 있습니다. 값은 백분율이 될 수 있습니다. 이 값 세트는 교차점을 계산하기 전에 루트 요소 경계 상자의 각 측면을 늘리거나 줄이는 역할을 합니다. 기본값은 다음과 같습니다. 모두 0입니다.
threshold
관찰자의 콜백이 실행되어야 하는 대상의 가시성 비율을 나타내는 단일 숫자 또는 숫자 배열입니다. 가시성이 50% 표시를 통과할 때만 감지하려는 경우 값 0.5를 사용할 수 있습니다. 가시성이 또 다른 25%를 지날 때마다 콜백을 실행하려면 배열 [0, 0.25, 0.5, 0.75, 1]을 지정합니다. 기본값은 0입니다(단 하나의 픽셀이라도 표시되는 즉시 콜백이 실행됨을 의미). 1.0 값은 모든 픽셀이 표시될 때까지 임계값이 통과된 것으로 간주되지 않음을 의미합니다.
우리 프로젝트에는 세 개의 파일이 있습니다.
. Styles.css
.card__container {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.card {
width: 400px;
height: 150px;
border-radius: 5px;
margin: 5px;
padding: 5px;
box-shadow: 1px 4px 5px 0.5px #ccc;
color: gray;
}
.button {
height: 40px;
}
.hidden {
opacity: 0;
transform: translateX(-100%);
filter: blur(5px);
transition: all 1s;
}
@media (prefers-reduced-motion) {
.hidden {
transition: none;
}
}
.show {
opacity: 1;
transform: translateX(0);
filter: blur(0);
}
가장 중요한 클래스는 "표시"와 "숨김"입니다.
.hidden {
opacity: 0;
transform: translateX(-100%);
filter: blur(5px);
transition: all 1s;
}
불투명도 0, translateX 및 블러 5px 위치 "-100%", 요소가 뷰포트에 진입하면 콜백 함수가 해당 요소에 "show" CSS 클래스를 추가합니다.
.show {
opacity: 1;
transform: translateX(0);
filter: blur(0);
}
1초의 "ease-out" 전환으로 모든 작업 가능
transition: all 1s ease-in-out;
@media (prefers-reduced-motion) {
.hidden {
transition: none;
}
}
<!DOCTYPE html>
<html>
<head>
<title>Intersection Observer API example</title>
<meta charset="UTF-8" />
<link rel="stylesheet" href="src/styles.css" />
</head>
<body>
<div id="app">
<h1>Intersection Observer API example</h1>
<p>
In this example we will demonstrate how to use the new build-in
Intersection Observer API
</p>
</div>
<div class="card__container">
<div id="card" class="card hidden">
<h1>Card1</h1>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
minim veniam...
</p>
</div>
<div id="card" class="card hidden">
<h1>Card2</h1>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
minim veniam...
</p>
</div>
<div id="card" class="card hidden">
<h1>Card3</h1>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
minim veniam...
</p>
</div>
<div id="card" class="card hidden">
<h1>Card4</h1>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
minim veniam...
</p>
</div>
<div id="card" class="card hidden">
<h1>Card5</h1>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
minim veniam...
</p>
</div>
<div id="card" class="card hidden">
<h1>Card6</h1>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
minim veniam...
</p>
</div>
<div id="card" class="card hidden">
<h1>Card7</h1>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
minim veniam...
</p>
</div>
<div id="card" class="card hidden">
<h1>Card8</h1>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
minim veniam...
</p>
</div>
<script defer src="src/index.js"></script>
</body>
</html>
문서가 완전히 로드될 때까지 자바스크립트 파일이 실행되지 않도록 합니다.
<script defer src="src/index.js"></script>
<div id="card" class="card hidden">
<h1>Card1</h1>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
minim veniam...
</p>
</div>
const hidden = document.querySelectorAll(".hidden");
const observer = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
entry.target.classList.add("show");
} else {
entry.target.classList.remove("show");
}
});
},
{
treshold: 0.5
// rootMargin:"-50px"
}
);
hidden.forEach((entry) => {
observer.observe(entry);
});
const hidden = document.querySelectorAll(".hidden");
const observer = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
entry.target.classList.add("show");
} else {
entry.target.classList.remove("show");
}
});
},
{
treshold: 0.5
// rootMargin:"-50px"
}
);
(entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
entry.target.classList.add("show");
} else {
entry.target.classList.remove("show");
}
});
}
그렇지 않으면 이 요소에서 제거합니다.
2. 옵션의 경우
{
treshold: 0.5
// rootMargin:"-50px"
}
우리의 경우 0.5는 요소의 절반이 뷰포트에 들어갈 때만 시작되는 애니메이션을 의미합니다.
RootMargin: "-50"을 사용하면 애니메이션이 시작 후 50px, 루트 요소의 및 앞 50px에서 시작됨을 의미합니다.
예를 들어 이 옵션을 사용하여 값이 100px인 뷰 포트(지연 로딩)에 들어가기 전에 이미지 로드를 시작할 수 있습니다.
{
...
// rootMargin:"100px"
}
여기에 다른 사례를 추가하겠습니다.
4개의 수평 요소가 있으며 지연을 추가하여 부드러운 수평 애니메이션을 표시할 수 있습니다.
이 부분을 "styles.css"에 추가하십시오.
.squares {
display: flex;
align-items: center;
margin: 10px;
margin-top: 400px;
}
.square {
width: 100px;
height: 100px;
margin: 2px;
background-color: #ccc;
text-align: center;
border: 2px solid #ccc;
font-size: 30px;
border-radius: 10px;
}
.square:nth-child(2) {
transition-delay: 100ms;
}
.square:nth-child(3) {
transition-delay: 220ms;
}
.square:nth-child(4) {
transition-delay: 360ms;
}
.square:nth-child(2) {
transition-delay: 100ms;
}
.square:nth-child(3) {
transition-delay: 220ms;
}
.square:nth-child(4) {
transition-delay: 360ms;
}
<div id="card" class="squares">
<div class="square hidden"><p>1</p></div>
<div class="square hidden"><p>2</p></div>
<div class="square hidden"><p>3</p></div>
<div class="square hidden"><p>4</p></div>
</div>

![연결된 목록이란 무엇입니까? [1 부]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































