화면 레이아웃

메인페이지 레이아웃

  • HTML/CSS가 제공되는 것을 기본으로 작성해야 하며, 메인페이지의 화면구성은 아래 기획서대로 보여야 한다.
  • GNB영역, 프로모션영역, 카테고리영역(6개의 메뉴구성). 상품리스트(기본 4개), 더보기 화면이 노출되야 한다.

기능

프로모션영역

  • 프로모션영역의 이미지는 1개보다 많으며, 자동으로 슬라이딩되어 넘어간다.
  • 슬라이딩 이미지는 애니메이션이 되면서 좌측으로 이동하는 것이 보여야한다.
  • 마지막 이미지에 다다르면 처음것이 그 다음으로 노출되야 한다. 마지막것에서 처음내용이 다시 보이는 부분은 끊겨서 노출되도 상관 없으며, 중요한 건 다시 처음부터 슬라이딩이 계속 되야 한다는 것이다. (엄격하진 않지만 최대한 자연스럽게 동작하려고 해야 한다)
  • 이동되는 속도는 적절하게 처리되면 된다.
  • 슬라이딩 이미지는 마우스나 터치에 반응하지는 않는다.

카테고리노출영역(탭UI)

  • 전체리스트가 Ajax를 통해서 화면에 4개의 아이템이 노출된다.
  • 탭별로 전체갯수가 상단에 노출되야 한다.
  • 각 아이템(전시상품)은 이미지/제목/장소/설명이 노출되야 한다.
  • 탭을 누르면 다른 카테고리 콘텐츠 4개가 다시 노출된다.
  • 더보기를 누르면 4개씩 노출되야 한다. 4개보다 적으면 적은 만큼 노출되야 한다.
  • 더보여줄 데이터가 없다면 더보기는 사라진다.
  • TOP영역이 선택되면, 화면 맨 위로 이동한다

소스코드

HTML,CSS

  • 제공되는 HTML/CSS를 수정할 수 있으며, 제공되는 코드의 형태의 구조를 지나치게 수정하지 않도록 한다.
  • 기존에 제공되는 class와 id규칙에 따라서 새로운 내용을 추가할 수 있다.
  • TABUI로 구성되는 카테고리 아이템이 노출 되는 영역의 HTML은 카테고리별로 각각 만들지 않고 하나로 만들어 재사용한다.

CSS3 를 사용한 애니메이션 구현

  • 상단영역의 애니메이션은 CSS3의 transition과 transform 속성을 JavaScript로 제어하면서 구현해야 한다.

효과적인 브라우저 기반 개발 방식사용

  • DOMContentloaded 이후에 모든 자바스크립트 로직이 동작되게 한다.
  • 카테고리 탭을 선택할 때마다, Ajax요청을 해서 데이터를 가져와야 한다.
  • 탭메뉴 (전시/뮤지컬/콘서트 등)는 Event delegation으로 구현한다.

JavaScript 코드 개선하기

  • Template 코드를 javascript 함수안에 보관하지 않고, 별도 분리시켜서 사용해야 한다. (HTML에 script태그 안에 보관한다던가)
  • 함수 하나에 여러개의 기능을 넣지 않고,함수를 여러개로 분리한다.

 

 

저번과 같은 실수를 하지 않기 위해 과제를 시작하기 전에 평가 기준표를 먼저 꼼꼼히 살펴보았다.

 

Promotion 부분의 자동 슬라이딩 기능을 추가하고, 전체적인 코드를 리팩토링 해야겠다고 생각이 들었고 이번 과제는 생각보다 금방 끝날 것 같았다.

 

하지만...

 

무한 자동 슬라이딩을 구현 하는 부분이 의외로 잘 되지 않았고 많은 시행 착오를 겪었다.(하루 종일 삽질...)

 

그 과정에서 addEventListener 의 첫번째 인자 값으로 들어가는 'transitionend' 을 알게 되었고, 하루 종일 했던 삽질이 정말 허무해질 만큼 간단하게 해결 할 수 있었다.

 

'transitionend' 를 첫번째 인자값으로 넣으면 어떻게 될까 ?

 

'click' 이 첫번째 인자값으로 들어갔을 때, 해당 html 요소 부분을 클릭하면 사용자가 설정해놓은 이벤트 함수를 실행한다.

 

'transitionend' 를 넣었을 때는 해당 html 요소 부분에서 변화가 감지 되었을 때 그 변화가 끝날 때 까지 기다렸다가 사용자가 설정한 이벤트 함수를 실행한다. 한 변화(transition)이 끝날때까지(end) 다른 행동들이 개입하지 못하게 한 뒤 설정 함수를 실행하는 것이다.

 

 

document.addEventListener("DOMContentLoaded", () => {
  initSlidePromotion();
  initTabCategory();
  viewTopBtn();
});

 

initSlidePromotion() 을 살펴보자.

  • 우선 initSlidePromotion() 에서 ajax 로 promotions 정보를 불러온 뒤 아래 함수들을 사용

  • createPromotionTemplate() : mainpage.jsp 파일에 만들어 놓은 promotionTemplate 에 위에서 받은 정보들을 넣는 함수

  • slidePromotion() : promotion 이미지들이 자동 슬라이딩 할 수 있도록 하는 함수

  • PROMOTION_IMAGE_WIDTH, SLIDE_SPEED 같은 값들은 상수로 따로 빼주었다.

 

 

우선 전체적인 코드 흐름은 이렇다.

  • initSlidePromotion() 에서 promotion 데이터들을 가져옴

  • promotionContainer 의 크기를 (promotionTotalCount + 1) * PROMOTION_IMAGE_WIDTH + 'px' 로 맞춤 (옆으로 개수만큼 쭈루룩 나열)

  • 가져온 데이터 들을 createPromotionTemplate() 함수를 통해 템플릿 작업을 하고 promotionContainer 뒤에 하나씩 추가해준다.

  • 여기서 중요한 점 !!!! 생각을 많이 해보았는데, 나는 마지막에서 다시 첫번째로 슬라이딩 할 때 첫번째 이미지를 마지막 다음에 하나 더 추가해주는 방법이 최선이라고 생각했다. 추가 하지 않고도 가능한 방법이 있는지 궁금하다.

  • 이미지도 추가해 주었겠다, 이제 슬라이딩 부분만 구현하면 된다.

  • 슬라이딩 부분은 requestAnimationFrame(slideTerm); 로 구현하였다.

    • 여기서 인자값으로 들어간 slideTerm 함수 안에는 setTimeout 을 사용하여 그 안에서 마지막에 다시 requestAnimationFrame(slideTerm) 을 불러주면서 다음 slideTerm 함수는 설정한 일정시간(슬라이딩 후 잠깐 대기하는 시간)이 지나면 실행하도록 하였다.

    • slideTerm 함수 안 내용은 promotion 의 html 요소 transform 을 바뀐 거리(movingDistance)로 움직이게 했다.

    • 인덱스도 하나씩 올려주면서 마지막 인덱스를 넘어가고 첫번째 이미지를 복사한 마지막 이미지에 도착했을 때 'transitionend' 이벤트 리스너에서 promotion 의 html 요소 transition 을 없애고 transform 을 'translateX(0)'으로 하여 바로 마지막에서 첫번째 같은 이미지로 넘어간다.

    • 다음 slideTerm 함수 에서는 인덱스를 1로 옮겨서 다시 처음부터 자동 슬라이딩이 실행된다. 'transitionend' 덕분에 부드러운 무한 슬라이딩이 가능했다.

 

예상치 못한 칭찬에 기분이 좋았다 :D

 

프로토타입 패턴이 뭘까 ?!? 바~~~~로 찾아보았다.

 

 

우선 프로토타입이라는게 무엇일까 ?

  • 자바스크립트의 모든 객체는 자신을 생성한 객체 원형에 대한 숨겨진 연결을 갖는다.

  • 이때 자기 자신을 생성하기 위해 사용된 객체원형을 프로토타입이란 한다.

  • 자바스크립트의 모든 객체는 Object 객체의 프로토타입을 기반으로 확장 되었기때문에 이 연결의 끝은 Object 객체의 프로토타입 Object 다.

이러한 프로토타입을 기반으로 한 프로그래밍은 무엇일까 ?

  • 객체의 원형인 프로토타입을 이용하여 새로운 객체를 만들어내는 프로그래밍 기법이다.

  • 이렇게 만들어진 객체 역시 자기자신의 프로토타입을 갖는다.

  • 이 새로운 객체의 원형을 이용하면 또 다른 새로운 객체를 만들어 낼수도 있으며 이런 구조로 객체를 확장하는 방식을 프로토타입 기반 프로그래밍이라고 한다. 

 

음.. javascript 에서 prototype 은 java 에서 class 를 상속하는 개념과 비슷한 것 같다. 프로토타입 패턴에 대해 조금 더 자세히 공부해보고 또 다른 javascript 의 디자인 패턴들을 공부해 봐야겠다.

 

 

 

for문에 들여쓰기가 되어있지 않았다. 이부분은 내가 확인을 못했던것 같다. for문 안의 코드를 들여쓰기 해주고 아래 if 문 조건문을 promotionTOtalCount !== 1 로 바꾸고 대괄호로 묶어주었다.

 

 

 

setInterval 함수는 시간이 정확히 맞지 않을때가 있다고 해서 setTimeout 을 썼지만 애니메이션이 간단할 경우에는 크게 상관이 없는 것 같다. 리뷰어님께서 말씀하신 것처럼 Promise, async await 등 javascript 의 비동기 프로그래밍을 좀 더 공부해봐야겠다.

 

 

 

이런 부분은 정말 생각을 못했다. 크롬에서만 테스트를 하면서 IE 환경에서 안될 수도 있다는 생각을 왜 못했을까...흠...

앞으로는 크로스 브라우징을 생각하며 코딩하는 습관을 길러야겠다.

 

 

현재 프로젝트 4도 거의 막바지 작업 중이라 얼른 끝내고 제출해서 리뷰 후기 글을 올려야겠다

 

 

 

 

 

 

 

 

#부스트코스

+ 따끈한 최근 게시물