[TIL] 210910

27685 단어 JavaScriptDOMTILDOM

📝 오늘 한 것

  1. carousel / display: none과 element.remove() 비교

  2. carousel 구현


📖 학습 자료

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

📚 배운 것

DOM


1. carousel(캐러셀)

(1) HTML 작성 → 뒤에서 수정

    <section>
      <div class="title-image-box">
        <img src="/images/vanilla_coding_logo.png" />
      </div>
      <h1>Carousel</h1>

      <!-- Carousel Start -->
      <div class="carousel-outer">
        <div class="carousel-image-and-arrow">
          <button type="button" class="carousel-arrow left">
            <i class="fas fa-arrow-circle-left"></i>
          </button>
          <div class="carousel-image-box">
            <img src="/images/image-1.png" alt="image-1" class="carousel-image">
          </div>
          <button type="button" class="carousel-arrow right">
            <i class="fas fa-arrow-circle-right"></i>
          </button>
        </div>
        <div class="carousel-dots">
          <button class="carousel-dot"></button>
          <button class="carousel-dot"></button>
          <button class="carousel-dot"></button>
          <button class="carousel-dot"></button>
          <button class="carousel-dot"></button>
        </div>
      </div>
      <!-- Carousel End -->
    </section>

(2) CSS 작성 → 뒤에서 수정

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}
>
html {
  width: 100%;
}
>
body {
  background-image: url("./images/bg.jpeg");
  background-repeat: no-repeat;
  background-size: cover;
  font-family: "Varela Round", sans-serif;
}
>
section {
  margin: 60px auto;
  max-width: 1000px;
}
>
.title-image-box {
  text-align: center;
  padding: 0 80px;
}
>
.title-image-box img {
  width: 100%;
  max-width: 800px;
}
>
h1 {
  font-family: "Pacifico", cursive;
  text-align: center;
  font-size: 5vw;
}
>
.carousel-outer {
  display: flex;
  flex-direction: column;
  align-items: center;
  background-color: white;
  margin: 20px auto;
  width: 80%;
}
>
.carousel-image-and-arrow {
  display: flex;
  justify-content: center;
  align-items: center;
  margin: 0 auto;
  width: 100%;
  margin-top: 50px;
}
>
.carousel-arrow {
  background-color: transparent;
  border-style: none;
  width: 120px;
}
>
.fa-arrow-circle-left,
.fa-arrow-circle-right {
  font-size: 30px;
  cursor: pointer;
}
>
.carousel-image-box {
  width: 70%;
  margin: 0 auto;
}
>
.carousel-image {
  width: 100%;
  vertical-align: middle;
}
>
.carousel-dot {
  background-color: transparent;
  border-style: none;
  cursor: pointer;
  font-size: 20px;
  line-height: 2.5;
  margin: 0 15px;
  color: grey;
}

💭 HTML은 짧은 만큼 쉽게 작성했는데 CSS는 각 컨테이너들의 width 부분에서 애를 좀 먹었다. 브라우저 창 크기를 줄일 때 HTML 영역 밖으로 자꾸 요소들이 빠져나가는 걸 해결하려고 오래 고민을 했는데 HTML 코드가 잘못되어 있었다. 다음부터 막힐 땐 진짜 꼭 HTML부터 보기로 다짐했다. 이 문제 관련해서도 지난번 portfolio 실습 때 완전히 익혔다고 생각했는데 아니었던 거 같다. 다시 한번 정리하는 시간을 가졌다. 각 컨테이너들에 색이 다른 테두리를 추가해서 살펴보는 게 도움이 많이 됐다.

(3) javascript 작성

  • 버튼이 눌렸을 때 현재 이미지를 display: none 처리하고, nextElementSiblingpreviousElementSiblingstyle() 메서드를 이용해 display: inline을 부여해주면 될 거 같다고 생각했음
  • 일단 HTML에 2~5번째 이미지들을 추가함
<div class="carousel-image-box">
  <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>
  • 그 후 CSS에서 2~5번째 이미지들에는 display: none을 부여해 처음 화면을 로딩할 때는 첫 번째 이미지만 나타나도록 해주었음
.two,
.three,
.four,
.five {
  display: none;
}
  • 자바스크립트에 이벤트를 등록함
// 우측 화살표 클릭 시 다음 이미지 보여주기
const rightArrow = document.querySelector('.right');

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

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

leftArrow.addEventListener('click', function goNext () {
  var presentImage = document.querySelector('.carousel-image');
  presentImage.style.display = 'none';
  presentImage.previousElementSibling.style.display = 'inline';
});
  • 이렇게 작성하니까 우측 화살표를 누르면 다음 이미지를 보여주긴 함
  • 그러나 한 번 더 누르면 반응이 없음
  • 왼쪽 화살표를 누르면 console 창에 이런 오류가 뜸
    TypeError: Cannot read properties of null (reading 'style') at HTMLButtonElement.goNext
  • 그렇다면 우측 버튼의 이전 형제 요소(div)의 자식 img를 preventImage 변수에 할당한다면?
const rightArrow = document.querySelector('.right');

rightArrow.addEventListener('click', function goBack (event) {
  var presentImage = event.currentTarget.previousElementSibling.children[0];
  presentImage.style.display = 'none';
  presentImage.nextElementSibling.style.display = 'inline';
});
  • 처음만 될 뿐, 두 번째부터는 눌러도 반응이 없다
  • ...느낌상 오히려 더 멀리 간 거 같아서 그냥 다시 돌아옴
  • 이번엔 현재 화면에 띄워져 있는 이미지(presentImage라는 변수)에 display: none을 설정해주는 대신, 아예 그 이미지를 삭제해 봄. 즉, presentImage.remove()
  • 드디어 우측 버튼을 누를 때마다 '연속으로' 다음 이미지로 넘어가도록 만들기 성공
// `우측` 화살표 클릭 시 다음 이미지 보여주기
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();
});
- 
  • 그러나 ❗ 좌측 버튼을 눌렀을 때 이전 이미지로 넘어가는 건 아직 안됨

💡 비교 !

  • display: none;

    • 해당 요소가 화면에 표시되지 않고, 그 요소에게 할당된 빈 공간조차 화면에서 사라진다
    • 자바스크립트에서 요소를 선택할 때 선택된다
  • element.remove();

    • 해당 요소를 아예 삭제한다
    • 자바스크립트에서 요소를 선택할 때 선택되지 않는다

✨ 내일 할 것

  1. carousel 구현 이어서

  2. 프로그래머스 알고리즘 문제 풀이 & 오답 분석

좋은 웹페이지 즐겨찾기