<div class="screen-images">
<img class="screenshot 1" src="img/screenimage1.jpg" alt="screen1"/>
<img class="screenshot 2" src="img/screenimage2.jpg" alt="screen2"/>
<img class="screenshot 3" src="img/screenimage3.jpg" alt="screen3"/>
<img class="screenshot 4" src="img/screenimage4.jpg" alt="screen4"/>
<img class="screenshot 5" src="img/screenimage5.jpg" alt="screen5"/>
</div>
시행착오를 많이 겪었다.
클래스를 붙였다 떼는 방식
유튜브에 검색해서 따라했는데, 출처를 확인할 수가 없다..
const firstSlide = document.querySelector('.screenshot:first-child');//첫번째 슬라이드는 .screenshot의 첫번째 자식이다.
setInterval(slide, 4000); //슬라이드 함수를 4초에 한 번씩 실행시킬 것
function slide(){
const showingClass = "showing";
const currentSlide = document.querySelector(`.${showingClass}`);
if(currentSlide){ //커런트 슬라이드가 있다면 이어서, 없다면 끝으로
firstSlide.classList.remove(showingClass);
//첫번째 슬라이드의 showing제거
const nextSlide = currentSlide.nextElementSibling;
//커런트슬라이드의 형제요소는 넥스트 슬라이드
if(nextSlide){ //넥스트 슬라이드가 있다면
currentSlide.classList.remove(showingClass);
//커런트 슬라이드의 showing제거
nextSlide.classList.add(showingClass);
//넥스트 슬라이드를 커런트 슬라이드로.
}else{ //넥스트 슬라이드가 없다면
currentSlide.classList.remove(showingClass);
//커런트 슬라이드의 showing제거
firstSlide.classList.add(showingClass);
//첫번째 슬라이드를 커런트 슬라이드로
}
}else{ //커런트슬라이드가 없다면 첫번째슬라이드가 커런트슬라이드가 된다.
firstSlide.classList.add(showingClass)
}
}
문제: 이미지 하나하나의 페이드만 되고 크로스페이드가 안된다.
배열api를 이용해서 이미지 순환시키기
const imageArr = ["img/screenimage1.jpg","img/screenimage2.jpg","img/screenimage3.jpg","img/screenimage4.jpg","img/screenimage5.jpg"];
//이미지 주소를 배열로 만든다.
const first = document.querySelector('.screenshot:nth-child(1)');
const second = document.querySelector('.screenshot:nth-child(2)');
const third = document.querySelector('.screenshot:nth-child(3)');
const fourth = document.querySelector('.screenshot:nth-child(4)');
const fifth = document.querySelector('.screenshot:nth-child(5)');
//1,2,3,4,5번째 슬라이드를 각각 선언해주고
first.setAttribute("src", imageArr[0]);
second.setAttribute("src", imageArr[1]);
third.setAttribute("src", imageArr[2]);
fourth.setAttribute("src", imageArr[3]);
fifth.setAttribute("src", imageArr[4]);
//각각의 src도 imageArr의 인덱스를 통해 설정해준다.
iterateImage 함수를 통해 imageArr의 인덱스를 순환시킨다.
function iterateImage(){
const firstElement = imageArr.shift();
//firstElement는 imageArr.shift 값이다.
//shift() 메서드는 배열에서 첫 번째 요소를 제거하고, 제거된 요소를 반환한다.
imageArr.push(firstElement);
//push() 메서드는 배열의 끝에 하나 이상의 요소를 추가하고, 배열의 새로운 길이를 반환한다.
// → shift된 첫번째 요소를 배열의 맨 뒤로 push한 새로운 배열이 반환된다.
first.setAttribute("src", imageArr[0]);
second.setAttribute("src", imageArr[1]);
third.setAttribute("src", imageArr[2]);
fourth.setAttribute("src", imageArr[3]);
fifth.setAttribute("src", imageArr[4]);
//이미지 태그는 가만히 있고, 태그 안의 src값만 순환하며 설정된다.
return imageArr;
}
setInterval(iterateImage, 5000);
문제: 이미지 순환의 문제는 없는데 크로스 페이드가 먹히지 않는다. 정확히는 처음한번만 fade-out 된다.
.screenshot {
position: absolute;
width: 240px;
height: 427px;
opacity: 1;
z-index: 0;
}
/*첫번째 슬라이드는 opacity 100% → 0% .*/
.screenshot:first-child {
z-index: 2;
opacity: 1;
animation: fade-out 5s linear;
}
.screenshot:nth-child(2) {
z-index: 1;
opacity: 1;
}
@keyframes fade-out {
/*점점 사라진다.*/
0%,
80% {
opacity: 1;
}
100% {
opacity: 0;
}
}
이유는 이미지 태그가 움직이는 게 아니라서 그런 것 같다. 첫번째 스크린샷의 이미지태그에 애니메이션을 적용했는데 변화하는 건 이미지 태그가 아니라 src라서...
방법 1을 참고해서 변형했다.
1) showClass, waitClass라는 2개의 클래스 달아주기
크로스페이드 트랜지션을 위해서는 보였다가 사라지는 이미지와 뒤에서 대기하는 이미지, 두 개의 엘리먼트가 필수적이다. 때문에 방법 1에서와 다르게 wait 클래스를 추가했다.
<div class="screen-images">
<img class="screenshot 1 show" src="img/screenimage1.jpg" alt="screen1"/>
<img class="screenshot 2 wait" src="img/screenimage2.jpg" alt="screen2"/>
<img class="screenshot 3" src="img/screenimage3.jpg" alt="screen3"/>
<img class="screenshot 4" src="img/screenimage4.jpg" alt="screen4"/>
<img class="screenshot 5" src="img/screenimage5.jpg" alt="screen5"/>
</div>
2) 클래스 돌리기
방법 1을 변형한 if문 알고리즘을 생각하다가 백번 정도 막혀서 처음에 사용했던 알고리즘을 두번 쓰기로 했다.
const firstSlide = document.querySelector('.screenshot:first-child');
setInterval(showSlide, 4900);
setInterval(waitSlide, 4900);
function showSlide(){
const showClass = "show";
const currentSlide = document.querySelector(`.${showClass}`);
if(currentSlide){ //커런트 슬라이드가 있다면 이어서, 없다면 끝으로
firstSlide.classList.remove(showClass);
//첫번째 슬라이드의 show제거
const nextSlide = currentSlide.nextElementSibling;
//커런트슬라이드의 형제요소는 넥스트 슬라이드
if(nextSlide){ //넥스트 슬라이드가 있다면
currentSlide.classList.remove(showClass);
//커런트슬라이드의 show제거
nextSlide.classList.add(showClass);
//넥스트 슬라이드를 커런트 슬라이드로
}else{ //넥스트 슬라이드가 없다면
currentSlide.classList.remove(showClass);
firstSlide.classList.add(showClass);
//첫번째 슬라이드를 커런트 슬라이드로
}
}else{ //커런트슬라이드가 없다면 첫번째 슬라이드가 커런트슬라이드가 된다.
firstSlide.classList.add(showClass)
}
}
function waitSlide(){
const waitClass = "wait"
const waitSlide = document.querySelector(`.${waitClass}`);
if(waitSlide){ //웨잇슬라이드가 있다면 이어서, 없다면 끝으로
secondSlide.classList.remove(waitClass);
//첫번째 슬라이드의 wait제거
const nextSlide = waitSlide.nextElementSibling;
//웨잇슬라이드의 형제요소는 넥스트 슬라이드
if(nextSlide){ //넥스트 슬라이드가 있다면
waitSlide.classList.remove(waitClass);
nextSlide.classList.add(waitClass);
//넥스트 슬라이드를 웨잇슬라이드로
}else{ //넥스트 슬라이드가 없다면
waitSlide.classList.remove(waitClass);
firstSlide.classList.add(waitClass);
//첫번째 슬라이드를 웨잇슬라이드로
}
}else{ //웨잇슬라이드가 없다면 첫번째 슬라이드가 웨잇슬라이드가 된다.
firstSlide.classList.add(waitClass)
}
}
두 함수가 아주 비슷하기 때문에 재사용이 가능하도록 합쳐서 바꾸었다.
const firstSlide = document.querySelector('.screenshot:first-child');
const showClass = "show";
const waitClass = "wait";
setInterval(function(){slide(showClass), slide(waitClass)}, 4900);
//4.9초 마다 두 함수 실행
function slide(theClass){
const theSlide = document.querySelector(`.${theClass}`);
//theSlide는 theClass가 선택자인 엘리먼트
if(theSlide){ //theSlide가 있다면 이어서, 없다면 끝으로
firstSlide.classList.remove(theClass);
//첫번째 슬라이드의 thsClass제거
const nextSlide = theSlide.nextElementSibling;
//theSlide의 형제요소는 넥스트 슬라이드
if(nextSlide){ //넥스트 슬라이드가 있다면
theSlide.classList.remove(theClass);
nextSlide.classList.add(theClass);
//넥스트 슬라이드를 theSlide로
}else{ //넥스트 슬라이드가 없다면
theSlide.classList.remove(theClass);
firstSlide.classList.add(theClass);
//첫번째 슬라이드를 theSlide로
}
}else{ //theSlide가 없다면 첫번째 슬라이드가 theSlide가 된다.
firstSlide.classList.add(theClass)
}
}
코드가 깔끔해졌다!😄
[TIL]