Ted's Codding study
0미니프로젝트 - imageGallery-vanilaJS 본문
0미니프로젝트 - imageGallery-vanilaJS Ted93 2024. 5. 16. 07:32
깃허브 : https://github.com/SeungjuShin93/imageGallery-vanilaJS
데모 : https://seungjushin93.github.io/imageGallery-vanilaJS/
HTML과 CSS는 간략하게 다루고 자바스크립트 위주로 글을 작성하겠습니다
요약 : 이미지 5장을 가지고,
서브 이미지 박스에서 이미지를 클릭하면 가운데 큰 이미지가
해당 클릭된 이미지로 바뀌는 이미지 갤러리 구현
추가적으로 다크 모드 버튼을 누르면 토글 버튼으로 써 다크 모드와 라이트 모드 구현
1. HTML
HTML 코드
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Image Gallery</title>
<link rel="stylesheet" href="style.css">
<script src="main.js" defer></script>
</head>
<body id="body">
<div class="wrapper">
<h1>Image Gallery Practice</h1>
<div class="container">
<div class="main-container">
<div id="overlay" class="main-overlay"></div>
<button id="main-btn" class="main-btn">다크 모드</button>
<img id="main-img" src="images/cat01.jpg" alt="고양이1">
</div>
<div id="sub-container" class="sub-container">
<img src="images/cat01.jpg" alt="고양이1">
<img src="images/cat02.jpg" alt="고양이2">
<img src="images/dog01.jpg" alt="강아지1">
<img src="images/dog02.jpg" alt="강아지2">
<img src="images/dog03.jpg" alt="강아지3">
</div>
</div>
</div>
</body>
</html>
- HTML 코드 설명
- 큰 틀로는, 전체를 감싸주는 박스를 wrapper로 만들어 줌
- 메인 이미지 박스와 서브 이미지 박스로 나누었음
- 메인 컨테이너에서 overlay는 다크 모드를 구현 시 어둡게 해주는 역할을 하는 박스임
- 메인 버튼은 다크 모드를 구현할 버튼
- 메인 이미지는 가장 크게 보일 이미지
- 서브 컨테이너 안의 이미지들은 밑에 클릭할 수 있는 이미지들임
- id로 선언된 것은 JS에서 DOM으로 활용할 요소들임을 암시
- class로 선언된 것은 CSS에서 스타일을 줄 요소들임을 암시
2. CSS
CSS 코드
body {
margin: 0;
}
body.dark {
background-color: rgba(0, 0, 0, 0.8);
color: white;
}
.wrapper {
width: 100%;
height: 100vh;
margin: auto;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
max-width: 1200px;
}
.wrapper h1 {
font-size: 2rem;
text-align: center;
}
.container {
width: 50%;
margin: 0 auto;
overflow: hidden;
border-radius: 5px;
}
.main-container {
position: relative;
width: 100%;
height: 50vh;
}
.main-overlay {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
background-color: rgba(0, 0, 0, 0);
color: black;
}
.main-btn {
position: absolute;
top: 2px;
left: 3px;
border: 1px solid #999;
border-radius: 3px;
width: 90px;
padding: 10px 0;
background-color: rgba(150, 150, 150, 0.6);
color: black;
}
.main-overlay.dark,
.main-btn.dark {
background-color: rgba(0, 0, 0, 0.5);
color: white;
}
.main-container img {
width: 100%;
height: 100%;
}
.sub-container {
display: flex;
width: 100%;
}
.sub-container img {
width: 20%;
}
@media (max-width: 1024px) {
.container {
width: 60%;
}
.wrapper h1 {
font-size: 1.5rem;
}
.main-container {
height: 40vh;
}
}
@media (max-width: 768px) {
.container {
width: 70%;
}
.wrapper h1 {
font-size: 1.2rem;
}
.main-container {
height: 30vh;
}
}
CSS 코드는 헷갈렸던 부분만 설명하겠습니다.
container 박스에 border-radius를 줬는데 처음에 작동하지 않았습니다.
그래서 생각했던 게 main-container 박스에서 아래와 같이
border-top-left-radius: 5px;
border-top-right-radius: 5px;
일일이 코딩을 했었습니다. 마찬가지로
sub-container 박스에 아래와 같이
border-bottom-left-radius: 5px;
border-bottom-right-radius: 5px;
주었었는데, 나중에 리팩토링을 하면서 학습을 통해서
그동안 다른 사람 코드에서 overflow:hidden이 왜 이리 많이 들어가나 싶었는데 (이론은 알고 있었지만 실제로 많은 페이지들을 인스펙션해서 overflow 속성을 지워도 차이를 못 느끼는 경우가 있어서 정확한 학습이 어려웠었음)
부모 컨테이너인 container에 border-radius를 주고 overflow:hidden;을 주면 된다는 것을 알게 되었습니다. overflow:hidden을 주기 전에는 자식 요소인 이미지가 모서리를 뚫고 나왔는데 이 옵션을 주게 되면 그 부분을 hidden 처리를 해주면서 원하는 방향으로 구현이 가능했다
요약하자면 아래 처럼만 하면 끝!
.container {
overflow: hidden;
border-radius: 5px;
}
3. JS
JS 코드
const body = document.getElementById('body');
const overlay = document.getElementById('overlay');
const mainBtn = document.getElementById('main-btn');
const mainImg = document.getElementById('main-img');
const subContainer = document.getElementById('sub-container');
mainBtn.addEventListener('click', darkMode);
subContainer.addEventListener('click', changeMainImg);
// dark 모드
function darkMode() {
body.classList.toggle('dark');
overlay.classList.toggle('dark');
mainBtn.classList.toggle('dark');
if (mainBtn.classList.contains('dark')) {
mainBtn.textContent = '라이트 모드';
} else {
mainBtn.textContent = '다크 모드';
}
}
// 그림 교체
function changeMainImg(e) {
const src = e.target.src;
const alt = e.target.alt;
mainImg.src = src;
mainBtn.alt = alt;
}
JS 코드 설명
다크모드 구현
메인 버튼을 클릭 시 다크 모드 함수 호출
- dark 클래스에 대한 CSS를 만들어 둘것
- mainBtn을 클릭했을 때 darkMode 함수를 실행하고 body, overlay, mainBtn에 ‘dark’ 라는 클래스 이름을 토글로 붙여줄 것 toggle은 스위치처럼 작동하며 클릭하면 dark 클래스가 생기고, 다시 클릭하면 dark 클래스가 없어짐
mainBtn.addEventListener('click', darkMode); function darkMode() { body.classList.toggle('dark'); overlay.classList.toggle('dark'); mainBtn.classList.toggle('dark'); }
- mainBtn에는 dark 모드가 적용되었을 때는 ‘라이트 모드’ 라는 글귀가 보이도록, dark 클래스가 없다면 ‘다크 모드’ 가 보이도록 할 것 contains는 dark글씨가 있다면 true를 반환, 없다면 false를 반환함
if (mainBtn.classList.contains('dark')) { mainBtn.textContent = '라이트 모드'; } else { mainBtn.textContent = '다크 모드'; }
이미지 교체 구현
- 5개의 이미지가 담겨 있는 부모인 박스 subcontainer에 click 이벤트를 걸어주면 changeMainImg 함수를 호출
subContainer.addEventListener('click', changeMainImg);
- changeMainImg 함수에는 이벤트를 인자인 e를 전달해주고 클릭된 이미지의 src 속성인 e.target.src 속성과 e.target.alt 속성을 const 변수인 src와 alt에 할당
- 할당된 src속성와 alt속성을 mainImg의 src와 alt에 각각 할당
function changeMainImg(e) { const src = e.target.src; const alt = e.target.alt; mainImg.src = src; mainBtn.alt = alt; }
간단한 JS 코드로도 그럴듯한? (제 생각뿐인가요 하하)
미니 프로젝트를 구현해 보아서 매우 뿌듯합니다~~
노션으로 보고 싶다면?
https://short-echidna-b16.notion.site/imageGallery-vanilaJS-c2d13c4a4e5943509004927dfb036f02?pvs=4
미니프로젝트 - imageGallery-vanilaJS | Notion
깃허브
short-echidna-b16.notion.site