요새는 스크롤 내리면 스르륵 등장하거나 뭐가 옆에서 툭 튀어나오거나 하는 그런 종류의 애니메이션이 많아졌다.
그거 우예함 하고 찾던 나는 저번에도 찾아봤지만, 뭔말이지... 했는데, 이번에도 유튜브의 이끌림으로 강의를 듣게 되었다.
아니 또 코딩애플센세!!!
뭐.. 코딩애플 강의를 듣고 한 번 이것저것 다뤄봤다.
나처럼 감도 못잡은 사람은 이 강의를 들어보면 될 듯 하다.
절대 광고 아님.
내 입맛대로 하다보니 html과 js가 살짝 다르긴하다.
코드는 아래처럼 강의를 했다.
전체 코드
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<style>
body{
background: black;
/* height: 6000px; */
}
div{
margin-top: 800px;
margin-bottom: 800px;
color: white;
text-align: center;
opacity: 0;
transition: all 1s;
}
</style>
<div id="first"><h1>iPhone 15출시</h1></div>
<div id="second"><h1>충전포트를 USB-C 타입으로 바꿔달라고요?</h1></div>
<div id="third"><h1>그래서 충전포트를 제거했습니다.</h1></div>
<div id="fourth"><h1>오 된다</h1></div>
<div id="fifth"><p>로또1등 당첨되면 바로 맥북max 사야징!!!!!</p></div>
<script>
let observer = new IntersectionObserver((e) => {
// 감시중 박스가 화면에 등장하면 여기 코드 실행해줌.
e.forEach((박스) => {
console.log(박스.target)
if(박스.isIntersecting){
박스.target.style.opacity = 1;
박스.target.style.transform = 'rotate(360deg)';
박스.target.style.transitionDuration = '0.5s';
} else{
// 감시중인 박스가 퇴장시 실행할 코드
박스.target.style.opacity = 0;
}
console.log(박스.intersectionRatio)
})
})
let div = document.querySelectorAll('div')
observer.observe(div[0]) // html요소가 화면에 등장하는지 감시해줌. 괄호안에 html요소 입력하면됨
observer.observe(div[1])
observer.observe(div[2])
observer.observe(div[3])
</script>
</body>
</html>
javascript 코드
<script>
let observer = new IntersectionObserver((e) => {
// 감시중 박스가 화면에 등장하면 여기 코드 실행해줌.
e.forEach((박스) => {
console.log(박스.target)
if(박스.isIntersecting){
박스.target.style.opacity = 1;
박스.target.style.transform = 'rotate(360deg)';
박스.target.style.transitionDuration = '0.5s';
} else{
// 감시중인 박스가 퇴장시 실행할 코드
박스.target.style.opacity = 0;
}
console.log(박스.intersectionRatio)
})
})
let div = document.querySelectorAll('div')
observer.observe(div[0]) // html요소가 화면에 등장하는지 감시해줌. 괄호안에 html요소 입력하면됨
observer.observe(div[1])
observer.observe(div[2])
observer.observe(div[3])
observer.observe(div[4])
</script>
여기선 우선 아이디 없이 div태그로만 진행을 했다.
let observer = new IntersectionObserve(()=>{})
이 코드를 통해 내가 감시하려는 녀석이 화면에 나타났을때 {}안에 있는 함수를 진행시킨다.
let div = document.querySelectorAll('div')
document.querySelectorAll('div')를 이용해서 모든 div를 찾아낸다.
그리고 observer변수(즉 IntersectionObserve)의 내장함수인 observe를 이용해서 각 div태그를 발견했을 때 위에서 말한 IntersectionObserve(() => {})의 함수를 실행시키도록 한다.
이렇게 하니 서서히 등장하는 모습을 확인 할 수 있었다.
HTML의 div태그들에 id를 한 번 달아봤다.
그리고 js를 수정해봤다.
html
<div id="first"><h1>iPhone 15출시</h1></div>
<div id="second"><h1>충전포트를 USB-C 타입으로 바꿔달라고요?</h1></div>
<div id="third"><h1>그래서 충전포트를 제거했습니다.</h1></div>
<div id="fourth"><h1>오 된다</h1></div>
<div id="fifth"><p>로또1등 당첨되면 바로 맥북max 사야징!!!!!</p></div>
js
<script>
let observer1 = new IntersectionObserver((e) => {
e.forEach((박스) => {
if(박스.isIntersecting){
박스.target.style.opacity = 1;
} else{
박스.target.style.opacity = 0;
}
})
})
let observer2 = new IntersectionObserver((e) => {
// 감시중 박스가 화면에 등장하면 여기 코드 실행해줌.
e.forEach((박스) => {
// console.log(박스.target)
if(박스.isIntersecting){
박스.target.style.opacity = 1;
박스.target.style.transform = 'rotate(360deg)';
박스.target.style.transitionDuration = '0.5s';
} else{
// 감시중인 박스가 퇴장시 실행할 코드
박스.target.style.opacity = 0;
}
// console.log(박스.intersectionRatio)
})
})
let observer3 = new IntersectionObserver((e) => {
// console.log(e)
e.forEach((entry)=>{
// 화면에 등장하면 => isIntersecting === true
if(entry.isIntersecting){
entry.target.style.opacity = 1;
switch (entry.target.id) {
case 'fifth':
entry.target.style.transform = 'translateX(30%)';
break;
default:
entry.target.style.transform = 'translateX(-30%)';
break;
}
}else{
entry.target.style.transform = 'translateX(0%)';
entry.target.style.opacity = 0;
}
})
})
let div = document.querySelectorAll('div')
observer1.observe(div[0]) // html요소가 화면에 등장하는지 감시해줌. 괄호안에 html요소 입력하면됨
observer1.observe(div[1])
observer2.observe(div[2])
observer3.observe(div[3])
observer3.observe(div[4])
</script>
각 div마다 다르게 표현해보고 싶어서 기존 observer 변수를 observer1, 2 3 로 만들고 시도해봤다.
잘 되는 것이 확인이 되었다.
observer1은 원래 계획대로 스윽 나타나고,
observer2는 360도 회전도 해주고,
observer3는 fourth는 왼쪽으로 fifth는 오른쪽으로 가는 모습을 볼 수 있었다.
다만 여기서 아쉬운 점은
let div = document.querySelectorAll('div')
observer1.observe(div[0])
observer1.observe(div[1])
observer2.observe(div[2])
observer3.observe(div[3])
observer3.observe(div[4])
이것을 다르게 할 수는 없을 까이다.
아마 중복되는 애니메이션을 줘야하는 뭔가가 있을 때, 이것은 #아이디명 이 아닌 .클래스명 을 이용해서 찾아야되지 않을까 한다.
아니면 document.querySelecotrAll이 아닌 document.querySelector()를 사용하는 방법도 있겠지.
일단 전체코드
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<style>
body{
background: black;
}
div{
margin-top: 800px;
margin-bottom: 800px;
color: white;
text-align: center;
opacity: 0;
transition: all 1s;
}
</style>
<div id="first"><h1>iPhone 15출시</h1></div>
<div id="second"><h1>충전포트를 USB-C 타입으로 바꿔달라고요?</h1></div>
<div id="third"><h1>그래서 충전포트를 제거했습니다.</h1></div>
<div id="fourth"><h1>오 된다</h1></div>
<div id="fifth"><p>로또1등 당첨되면 바로 맥북max 사야징!!!!!</p></div>
<script>
let observer1 = new IntersectionObserver((e) => {
e.forEach((박스) => {
if(박스.isIntersecting){
박스.target.style.opacity = 1;
} else{
박스.target.style.opacity = 0;
}
})
})
let observer2 = new IntersectionObserver((e) => {
// 감시중 박스가 화면에 등장하면 여기 코드 실행해줌.
e.forEach((박스) => {
// console.log(박스.target)
if(박스.isIntersecting){
박스.target.style.opacity = 1;
박스.target.style.transform = 'rotate(360deg)';
박스.target.style.transitionDuration = '0.5s';
} else{
// 감시중인 박스가 퇴장시 실행할 코드
박스.target.style.opacity = 0;
}
// console.log(박스.intersectionRatio)
})
})
let observer3 = new IntersectionObserver((e) => {
// console.log(e)
e.forEach((entry)=>{
// 화면에 등장하면 => isIntersecting === true
if(entry.isIntersecting){
entry.target.style.opacity = 1;
switch (entry.target.id) {
case 'fifth':
entry.target.style.transform = 'translateX(30%)';
break;
default:
entry.target.style.transform = 'translateX(-30%)';
break;
}
}else{
entry.target.style.transform = 'translateX(0%)';
entry.target.style.opacity = 0;
}
})
})
let div = document.querySelectorAll('div')
observer1.observe(div[0]) // html요소가 화면에 등장하는지 감시해줌. 괄호안에 html요소 입력하면됨
observer1.observe(div[1])
observer2.observe(div[2])
observer3.observe(div[3])
observer3.observe(div[4])
</script>
</body>
</html>
우리의 친구 gpt한테 한 번 물어봤다.
js 코드를 아래처럼 바꿔보란다.
<script>
// 공통 옵저버 콜백 함수
const observerCallback = (entries, observer) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
const targetId = entry.target.id;
entry.target.style.opacity = 1;
switch (targetId) {
case 'third':
// 'third'에 대한 특별한 애니메이션
entry.target.style.transform = 'rotate(360deg)';
entry.target.style.transition = 'opacity 1s, transform 0.5s';
break;
case 'fourth':
case 'fifth':
// 'fourth'와 'fifth'에 대한 특별한 애니메이션
const translateXValue = targetId === 'fifth' ? '30%' : '-30%';
entry.target.style.transform = `translateX(${translateXValue})`;
entry.target.style.transition = 'opacity 1s, transform 1s';
break;
default:
// 기본 애니메이션
entry.target.style.transition = 'opacity 1s';
break;
}
} else {
// 요소가 뷰포트에서 벗어났을 때 초기 상태로 복귀
entry.target.style.opacity = 0;
entry.target.style.transform = 'translateX(0%)'; // 초기 위치로 복귀
// 'third'에 적용된 회전 초기화
if (entry.target.id === 'third') {
entry.target.style.transform = 'rotate(0deg)';
}
}
});
};
// 옵저버 인스턴스 생성
const observer = new IntersectionObserver(observerCallback);
// 모든 'div' 요소에 대해 옵저버 등록
document.querySelectorAll('div').forEach((div) => {
observer.observe(div);
});
</script>
이렇게 하니 내가 만든 코드 처럼 작동을 해준다.
observerCallback이라는 함수를 생성했는데,
기존 IntersectionObserver((() => {}) 대신에
IntersectionObserver(observerCallback)처럼 사용을 하는 모습이다.
그리고 내가 observer 1, 2, 3를 나눈 것을 하나로 합치고, 그 안에서 switch-case문을 이용해서 각각에 맞는 상황을 만들어줬다. 만약 더 자세하게 하고 싶다면,
if (entry.isIntersecting){
switch(){
case:
}
}else{}
만 하는게 아닌
if (entry.isIntersecting){
switch(){
case:
}
}else{
switch(){
case:
}
}
로 사용하면 되지 않을까 싶다.
아직 초보인 나에겐 이렇게 하는게 더 나은 선택인 듯 하다.
이런 것도 알게 되어서 너무 씐나는군.
gpt를 통한 전체코드
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<style>
body{
background: black;
}
div{
margin-top: 800px;
margin-bottom: 800px;
color: white;
text-align: center;
opacity: 0;
transition: all 1s;
}
</style>
<div id="first"><h1>iPhone 15출시</h1></div>
<div id="second"><h1>충전포트를 USB-C 타입으로 바꿔달라고요?</h1></div>
<div id="third"><h1>그래서 충전포트를 제거했습니다.</h1></div>
<div id="fourth"><h1>오 된다</h1></div>
<div id="fifth"><p>로또1등 당첨되면 바로 맥북max 사야징!!!!!</p></div>
<script>
// 공통 옵저버 콜백 함수
const observerCallback = (entries, observer) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
const targetId = entry.target.id;
entry.target.style.opacity = 1;
switch (targetId) {
case 'third':
// 'third'에 대한 특별한 애니메이션
entry.target.style.transform = 'rotate(360deg)';
entry.target.style.transition = 'opacity 1s, transform 0.5s';
break;
case 'fourth':
case 'fifth':
// 'fourth'와 'fifth'에 대한 특별한 애니메이션
const translateXValue = targetId === 'fifth' ? '30%' : '-30%';
entry.target.style.transform = `translateX(${translateXValue})`;
entry.target.style.transition = 'opacity 1s, transform 1s';
break;
default:
// 기본 애니메이션
entry.target.style.transition = 'opacity 1s';
break;
}
} else {
// 요소가 뷰포트에서 벗어났을 때 초기 상태로 복귀
entry.target.style.opacity = 0;
entry.target.style.transform = 'translateX(0%)'; // 초기 위치로 복귀
// 'third'에 적용된 회전 초기화
if (entry.target.id === 'third') {
entry.target.style.transform = 'rotate(0deg)';
}
}
});
};
// 옵저버 인스턴스 생성
const observer = new IntersectionObserver(observerCallback);
// 모든 'div' 요소에 대해 옵저버 등록
document.querySelectorAll('div').forEach((div) => {
observer.observe(div);
});
</script>
</body>
</html>