TIL
[클라우딩 어플리케이션 엔지니어링 TIL] - 7주차 고양이 검색 사이트
blackmilktea
2024. 5. 29. 23:57
고양이 검색 사이트 만들기
요구사항
1. HTML, CSS 관련
● 현재 HTML 코드가 전체적으로 <div> 로만 이루어진 이 마크업을 시맨틱한 방법으로 변경
=> 의미없는 <div>를 <section>으로 변경
● 유저가 사용하는 디바이스의 가로 길이에 따라 검색결과의 row 당 column 갯수를 적절히 변경
○ 992px 이하: 3개
○ 768px 이하: 2개
○ 576px 이하: 1개
@media screen and (max-width: 992px) {
.SearchResult {grid-template-columns: repeat(3, minmax(250px, 1fr));}
}
@media screen and (max-width: 768px) {
.SearchResult {grid-template-columns: repeat(2, minmax(250px, 1fr));}
.ImageInfo .content-wrapper {width: 100%;}
}
@media screen and (max-width: 576px) {
.SearchResult {grid-template-columns: repeat(1, minmax(250px, 1fr));}
}
● 다크 모드(Dark mode)를 지원하도록 CSS를 수정
○ 모든 글자 색상은 #FFFFFF , 배경 색상은 #000000 로 한정
○ 기본적으로는 OS의 다크모드의 활성화 여부를 기반으로 동작하게 하되, 유저가 테마를 토글링 할 수 있도록 좌측 상단에 해당 기능을 토글하는 체크박스 구현
class DarkModeToggle {
isDarkMode = null;
constructor({$target}) {
const $wrapper = document.createElement("section")
const $DarkModeToggle = document.createElement("input");
this.$DarkModeToggle = $DarkModeToggle;
this.$DarkModeToggle.type = "checkbox"
$DarkModeToggle.className = "DarkModeToggle";
$wrapper.appendChild($DarkModeToggle);
$target.appendChild($wrapper);
$DarkModeToggle.addEventListener("change", e => {
this.setColorMode(e.target.checked);
});
this.initColorMode();
}
initColorMode() {
// matchMedia로 os의 컬러모드 확인
this.isDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches;
this.$DarkModeToggle.checked = this.isDarkMode;
this.setColorMode(this.isDarkMode)
}
setColorMode(isDarkMode) {
document.documentElement.setAttribute('color-mode', isDarkMode ? 'dark' : 'light');
}
}
// 다크 모드 적용 css
:root[color-mode="dark"] {
--background: #000;
--textColor: white;
}
body * {
background-color: var(--background);
color: var(--textColor);
}
2. 이미지 상세 보기 모달 관련
● 디바이스 가로 길이가 768px 이하인 경우, 모달의 가로 길이를 디바이스 가로 길이만큼 100%
● 필수 이미지를 검색한 후 결과로 주어진 이미지를 클릭하면 모달이 뜨는데, 모달 영역 밖, ESC 키, 모달 우측의 닫기(x) 버튼을 누르면 닫히도록 수정
● 모달에서 고양이의 성격, 태생 정보를 /cats/:id 를 통해 렌더링
// 이미지 클릭시 모달 제어
/* api.js */
fetchCatDetail: async id => { // id를 통해 고양이 상세 정보 가져오기
const res = await fetch(`${API_ENDPOINT}/api/cats/${id}`);
return await res.json();
}
/* ImageInfo.js */
showDetail(data) { // 정보 갱신
api.fetchCatDetail(data.cat.id).then(({data}) => {
this.setState({visible:true, cat: data});
});
}
/* App.js */
this.searchResult = new SearchResult({
$target,
initialData: this.data,
onClick: cat => { // 클릭시 showDetail 실행
this.imageInfo.showDetail({visible: true, cat});
}
});
// 모달 닫기
/* ImageInfo.js */
closeImageInfo() {
this.setState({
visible: false, cat: undefined});
}
render {
//...
document.addEventListener('keypress', (e) => {
if (e.key === 'Escape') this.closeImageInfo();
});
this.$imageInfo.addEventListener('click', (e) => {
if (e.target.className === 'ImageInfo' ||
e.target.className === 'close') this.closeImageInfo();
});
}
keypress, keydown, keyup
- keypress: 키보드를 누를 때 실행, 키를 계속 누르고 있으면 연속적으로 실행, 한글 인식 못함.
- keydown: 키보드를 누를 때 실행, 키를 계속 누르고 있어도 단 한 번만 실행 , 모든 문자 인식
- keyup: 키보드를 뗄 때 실행
키를 누르면 keydown -> keypress 순으로 실행되고 키가 해제되면 keyup이 실행