본문 바로가기
카테고리 없음

하나투어 반응형 웹 프로젝트 회고 및 코드

by 경험을 기록하다. 2025. 4. 28.

1. CSS 스타일 파일 분류

css 파일을 분리했다. 레이아웃 관련된 속성은 layout.css 디자인 관련된 속성은 main.css 공통은 common.css

 

css 파일


2. 헤더 마크업 분석 및 구조

실제 사이트는 뷰포트 기반으로 제작된 반응형 웹 사이트였다. 디자인 시안만 확인하고 rem 단위를 이용해 제작하는 목표를 설정하였다.

 

하나투어 GNB


3. 콘텐츠 마크업 구조

디자인 시안에서 가로 콘텐츠이었고, 드래그 앤 드래그 애니메이션이고 요소가 다소 있었다. 어떤 태그여야 할까? 공통 스타일을 어떻게 하면 좋을까? 등을 고민을 했다. 드래그 앤 드래그는 GSAP 라이브러리를 사용했다.

 

하나투어 콘텐츠
하나투어 콘텐츠


4. 웹 표준 준수

배포하고 보니 img 태그 alt 부분을 준수하지 않아서 수정했고 그 외 라벨, 폼 등을 태그도 수정했다.

 

웹 표준 준수한 화면


5. 비주얼 슬라이더 버튼 클릭 시 영상 재생/정지 버튼

문제

만약에 슬라이더 요소가 추가되면 버튼이 동작해야 되는데 오류 대응을 하지 않고 구현을 했다가 발생된 문제다. 슬라이더 요소 하나 더 추가하고 버튼을 클릭하니까 영상이 정지가 되지 않고 첫 번째 영역의 슬라이더만 정지가 됐다.

Github에서 전체 코드 보기

https://github.com/wangkodok/hanatourcompany/commit/871a7222944434b6fd00ad37da675f501dc576f2

 

fix:비주얼 슬라이더 영상 재생/정지 버튼 동작 오류 수정 · wangkodok/hanatourcompany@871a722

@@ -61,15 +61,15 @@ window.addEventListener("DOMContentLoaded", () => {

github.com

코드 수정 후

슬라이더 요소가 추가가 된다면 대처하는 코드로 작성하지 않았다.

 

// 버튼 클릭 시 영상 재생, 정지
const videoPlayer = document.querySelector("#video-player");
const video = document.querySelector(".video")
videoPlayer.addEventListener("click", function () {
  if (video.paused || video.ended) {
    video.play(); // 재생
    videoPlayer.classList.remove("active");
  } else {
    video.pause(); // 정지
    videoPlayer.classList.add("active");
  };
});

코드 수정 후

슬라이더 버튼을 클릭하면 해당하는 영역의 버튼이 활성화하고 재생/정지 버튼을 클릭을 할 수 있도록 코드를 추가 및 수정을 했다.

  // 비주얼 슬라이더 버튼 클릭 시 영상 재생/정지 버튼
  const visualSlide = document.querySelectorAll("#visual-slide .swiper-slide");
  const paginationBullets = document.querySelectorAll('.swiper-pagination button');
  const videoPlayer = document.querySelector("#video-player");

  const buttonActive = "swiper-pagination-bullet-active";
  paginationBullets.forEach((buttonItem) => {
    buttonItem.addEventListener("click", () => {
      if (!buttonItem.classList.contains(buttonActive)) {
        visualSlide.forEach((item) => {
          item.querySelector(".video").play();
          videoPlayer.classList.remove("active");
        });
      };
    });
  });

  videoPlayer.addEventListener("click", () => {
    visualSlide.forEach((item) => {
      if (item.classList.contains("swiper-slide-active")) {
        if (item.querySelector(".video").paused || item.querySelector(".video").ended) {
          item.querySelector(".video").play(); // 재생
          videoPlayer.classList.remove("active");
        } else {
          item.querySelector(".video").pause(); // 정지
          videoPlayer.classList.add("active");
        };
      };
    });
  });