잡다한 배똥월드

728x90

이미지 상세 보기 모달 관련

  • 디바이스 가로 길이가 768px 이하인 경우, 모달의 가로 길이를 디바이스 가로 길이만큼 늘려야 합니다.
  • 필수 이미지를 검색한 후 결과로 주어진 이미지를 클릭하면 모달이 뜨는데, 모달 영역 밖을 누르거나 / 키보드의 ESC 키를 누르거나 / 모달 우측의 닫기(x) 버튼을 누르면 닫히도록 수정해야 합니다.
  • 모달에서 고양이의 성격, 태생 정보를 렌더링합니다. 해당 정보는 /cats/:id 를 통해 불러와야 합니다.
  • 추가 모달 열고 닫기에 fade in/out을 적용해 주세요.

 


 

1. 모달 가로 길이

     ImageInfo.js의 render() 내에 추가하기

if (window.innerWidth < 768) {
	document.querySelector(".content-wrapper").style.width = window.innerWidth + "px";
}

 

2. 모달 종료

class ImageInfo {
  $imageInfo = null;
  data = null;

  constructor({ $target, data }) {
    const $imageInfo = document.createElement("div");
    $imageInfo.className = "ImageInfo";
    this.$imageInfo = $imageInfo;
    $target.appendChild($imageInfo);

	//1번 : 모달 영역 밖 눌러서 종료
    $imageInfo.addEventListener("click", function(e){
      if ($imageInfo == e.target) {
        closeModal();
      }
    });

	//2번 : esc키 눌러서 종료
    window.addEventListener("keydown", function(e){
      if (e.keyCode == 27 && $imageInfo.style.display != "none") {
        closeModal();
      }
    })

    this.data = data;

    this.render();
  }

  setState(nextData) {
    this.data = nextData;
    this.render();
  }

  render() {
    if (this.data.visible) {
      console.log(this.data.image);
      const { name, url, temperament, origin } = this.data.image;

      this.$imageInfo.innerHTML = `
        <div class="content-wrapper">
          <div class="title">
            <span>${name}</span>
            <div class="close">x</div>
          </div>
          <img src="${url}" alt="${name}"/>        
          <div class="description">
            <div>성격: ${temperament}</div>
            <div>태생: ${origin}</div>
          </div>
        </div>`;
      this.$imageInfo.style.display = "block";

      if (window.innerWidth < 768) {
        resizeModal();
      }

	  //3번 : x 버튼 눌러서 종료
      const close = document.querySelector(".close");
      close.addEventListener("click", closeModal);
      close.style.cursor = "pointer";

    } else {
      this.$imageInfo.style.display = "none";
    }
  }
}

function closeModal() {
  const target = document.querySelector(".ImageInfo");
  target.style.display = "none";
}

function resizeModal() {
  const modal = document.querySelector(".content-wrapper");
  modal.style.width = window.innerWidth + "px";
}

 

3. 고양이의 성격, 태생 정보를 렌더링

     - api.js에 추가

 fetchModal: id => {
    try {
      return fetch(`${API_ENDPOINT}/api/cats/${id}`).then(res =>
        res.json()
      ).then(data => data);
    } catch (e) {
      console.log(e);
    }
}

 

   - App.js에서 변경

    this.searchResult = new SearchResult({
      $target,
      initialData: this.data,
      onClick: async image => {
        const {data} = await api.fetchModal(image.id);
        this.imageInfo.setState({
          visible: true,
          image: data
        });
      }
    });

여기서 조금 많이 어려웠는데, 일단 api에서 코드 작성하는 것의 쉬웠음

근데 그 후 데이터를 활용하는 데에 어려움을 느꼈는데, async랑 await을 쓰니까 바로 해결됬고, 이게 리턴값이 promise라서 그렇다고는 하는데, 나중에 좀 더 공부를 해야하는 부분이라고 생각했음.

↓ 참고 링크 ↓

 

JavaScript - 자바스크립트 fetch와 async/await

컴퓨터/IT/알고리즘 정리 블로그

chanhuiseok.github.io

 

 

4. fade in/out

     - ImageInfo.js에 추가해서 모달이 생길 때와 사라질 때 각각 함수 추가하기

function fadeIn(target) {
  var opacityNum = 0;

  var interval = setInterval(function() {
    if (opacityNum > 1) clearInterval(interval);

    opacityNum += 0.1;
    target.style.opacity = opacityNum;
  }, 10);
}

function fadeOut(target) {
  var opacityNum = 1;

  var interval = setInterval(function() {
    if (opacityNum < 0) {
      clearInterval(interval);
      target.style.display = "none";
    }

    opacityNum -= 0.1;
    target.style.opacity = opacityNum;
  }, 10);
}

 

 

 

728x90

+ Recent posts