[TIL] 210911

Lee Syong·2021년 9월 11일
0

TIL

목록 보기
24/204
post-thumbnail

📝 오늘 한 것

  1. carousel 구현 중

📖 학습 자료

  1. 사전 학습 가이드 STEP 4 (carousel)

📚 배운 것

DOM


1. carousel(캐러셀)

어제 풀이에서 이어서

(1) javascript 작성

  • 현재 '우측 버튼' 누를 때마다 '연속으로' 다음 이미지로 넘어가도록 만드는 데까지 구현된 상태
// `우측` 화살표 클릭 시 다음 이미지 보여주기
const rightArrow = document.querySelector('.right');

rightArrow.addEventListener('click', function goBack () {
  var presentImage = document.querySelector('.carousel-image');
  presentImage.nextElementSibling.style.display = 'inline';
  presentImage.remove();
});

// `좌측` 화살표 클릭 시 이전 이미지 보여주기
const leftArrow = document.querySelector('.left');

leftArrow.addEventListener('click', function goNext () {
  var presentImage = document.querySelector('.carousel-image');
  presentImage.previousElementSibling.style.display = 'inline';
  presentImage.remove();
});
  • 그러나 ❗ '좌측 버튼'을 눌렀을 때 이전 이미지로 넘어가는 ęą´ 아직 안되는 상태
  • 좌측 버튼 식에서 presentImage 변수가 갖는 값이 무엇인지 알아보기 위해 console.log 실행해봤더니 이렇게 떴다
  var presentImage = document.querySelector('.carousel-image');
  console.log(presentImage); // 3번째 이미지 출력
  console.log(presentImage.nextElementSibling); // 4번째 이미지 출력
  console.log(presentImage.previousElementSibling); // null
  • console 창에 오류도 뜸
    Uncaught TypeError: Cannot read properties of null (reading 'style') at HTMLButtonElement.goNext
  • 즉, presentImage.previousElementSibling가 null이라 몝 읽는다는 뜻
  • 그렇다면 이전 요소나 다음 요소나 똑같이 HTML에는 display: none이 적용되어 있는데 왜 다음 요소만 찍히고 이전 요소는 안 찍히는 걸까
  • 일단 display: noneęłź 관련이 있나 싶어서 'display: none null'로 검색
  • 숨기고 싶은 이미지들에 display: none을 설정하는 대신 position: absolute뼟 이용해서 우주 공간으로 보내버리는 방법이 있대서 시도해 봄
position: absolute;
top: -9999px;
left: -9999px;
  • 2~5번째 이미지 부분 CSS에 display: none 대신 이 내용을 추가하고 자바스크립트 이벤트 리스너의 style.display 부분도 position으로 수정
  • 그러나 역시 안됨
  • 검색을 더 하다가 addEventListener 대신 onclick을 써보라는 조언을 봐서 해봤는데 안됨
  • 이왕 검색해본 김에 배운 내용은 정리했음

💡 click과 onclick의 차이점

(1) 꾏돸

  • click
element.addEventListener('click', function () {
  // 이벤트 리스너 즉, 함수 내용
});
  • onclick
element.onclick = function () {
  // 함수 내용
}

(2) 버블링, 캡쳐링 설정 여부

  • click: 이벤트 리스너의 3번째 매개변수에 true/false 값 넣어서 설정 가능
  • onlick : 설정 불가능

(3) 한 요소에 여러 개의 클릭 이벤트가 등록되었을 때 처리 여부
= 클릭 이벤트 리스너가 여러 개일 때, onclick 구문이 여러 개일 때

  • click : 이벤트 리스너 누적 실행 가능
  • onclick: 누적 실행 불가능, 덮어쓰기 되어서 마지막 구문만 실행됨
  • 이건 이거고 다시 본론으로 돌아와서, 문제가 display: none도 아니고 click도 아니라면 아예 previousElementSibling 자체가 문제 아닐까 싶어서 previousElementSibling null로 검색해 봄
  • mdn 사이트에서 정의 부분을 번역해보면
    • Element.previousElementSibling 읽기 전용 속성은 부모의 자식 목록에서 지정된 요소 바로 앞의 요소를 반환한다. 지정된 요소가 목록의 첍 번째 요소인 경우에는 null을 반환한다.
  • 🤨??? 위에서 console.log 출력했던 값을 다시 가져오면,
  var presentImage = document.querySelector('.carousel-image');
  console.log(presentImage); // 3번째 이미지 출력
  console.log(presentImage.nextElementSibling); // 4번째 이미지 출력
  console.log(presentImage.previousElementSibling); // null
  • 지정된 요소 즉, presentImage가 목록의 첍 번째 요소가 아니고 3번째 요소인데도 null 값이 출력되는 ęą´ 왜죠? nextElementSibling은 잘만 나오는데 previousElementSibling은 왜 안 나오는 걸까.
  • 좌측 화살표를 연구하고 있었는데 검색을 하는 중에 어쩌다가 '5번째 이미지에서 우측 화살표를 누를 경우, 1번째 이미지 보여주기'로 넘어옴
const rightArrow = document.querySelector('.right');

rightArrow.addEventListener('click', function goBack () {
  var presentImage = document.querySelector('.carousel-image');

  // 마지막(5번째) 이미지에서 우측 화살표를 클릭 시, 첫 번째 이미지 보여주기
  if (presentImage === presentImage.parentElement.lastElementChild) {

    var firstImage = presentImage.parentElement.firstElementChild; // 여기서 firstImage 변수에 첫 번째 img를 할당해 주었는데

    console.log(presentImage); // 마지막 img 요소가 출력됨
    console.log(firstImage); // 💢 문제 발생 ❗ console 창에 첫 번째 img 요소가 아니라 여기서도 마지막 img 요소가 출력됨

    firstImage.style.display = 'inline'; // 즉, 여기서는 마지막 이미지에 display: inline을 적용한 것이 되고
    presentImage.remove(); // display: inline 적용한 이미지를 여기서 삭제한 거임
    // → 당연히 원래 화면에 보이던 마지막 img만 사라질 뿐, 첫 번째 img가 뜰 리 만무함
  }

  // 나머지(1~4번째) 이미지에서 우측 화살표 클릭 시, 다음 이미지 보여주기
  else {
    console.log(presentImage);
    console.log(presentImage.nextElementSibling);

    presentImage.nextElementSibling.style.display = 'inline';
    presentImage.remove();
  }
});
  • display: none 대신에 z-index뼟 사용해 보기로 함
  • z-index뼟 적용하기 위해서 img 요소들에 position: absolute뼟 지정해주니까 img가 붕 떠 버리고, 부모 요소인 .carousel-image-box의 높이는 0이 됨
  • ꡸냼 부모 요소에 고정값의 높이를 지정해주는 ęą° 말고, 반응형을 유지하면서 이 문제를 해결하기 위해 또 검색을 하다가 아래 방법을 발견해서 적용하긴 했다
  • 근데 이게 추후 자바스크립트 구현에 방해가 될 ęą° 같은 불길한 느낌적인 느낌
<div class="carousel-image-box">
            <img src="images/image-3.png" class="invisible">
            // ↑ 해결을 위해 추가한 요소
            <img src="/images/image-1.png" alt="image-1" class="carousel-image one">
            <img src="/images/image-2.png" alt="image-2" class="carousel-image two">
            <img src="/images/image-3.png" alt="image-3" class="carousel-image three">
            <img src="/images/image-4.png" alt="image-4" class="carousel-image four">
            <img src="/images/image-5.png" alt="image-5" class="carousel-image five">
          </div>
.carousel-image-box {
  position: relative;
  width: 70%;
  margin: 0 auto;
}

// 해결을 위해 추가한 요소의 CSS
.invisible {
  width: 100%;
  vertical-align: middle;
  visibility: hidden;
}

.carousel-image {
  position: absolute;
  width: 100%;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

.one {
  z-index: 4;
}

.two {
  z-index: 3;
}

.three {
  z-index: 2;
}

.four {
  z-index: 1;
}

.five {
  z-index: 0;
}
  • 멍청하게도 사전 학습 가이드 권고 사항을 밊금 발견함
// 이미지 변경은 아래와 같이 이미지 요소의 src를 변경하는 방식으로 하는 것을 권장합니다.
someImageElement.src = "/images/image-1.png";
  • style.display: none만 쓰려고 했는데 이미지 주소 속성을 아예 바꿔버리는 방법도 있었음

💭 이후로 온갖 걸 다 해봤는데 안타깝게도 오늘 안에 해결이 안 됐다. 실패한 코드들까지 그때그때 블로그에 기록하던 것도 올스톱 하고 하루종일 이것저것 시도를 해봤는데 안됨. carousel 직접 검색은 피하다가 방금 전에 슬쩍 검색해 봤는데 내가 흐린 눈으로 봐서 그런지는 몰라도 carousel에도 종류가 여러 가지라 이 경우는 잘 뜨지도 않는 거 같음.

하다하다 안 되면 유료 강의를 찾아서 보더라도 이해하고야 만다 내가. 이쯤 되면 오기 생겨서 안 되겠음. 누가 이기나 해보자.


✨ 내일 할 것

  1. carousel 구현 마무리
profile
능동적으로 살자, 행복하게😁

0개의 댓글