드롭박스에 영화 목록을 보여주고 좌석 배치도에는 자리 하나 하나를 클릭해서 차지할 수 있도록 한다. 차지한 좌석 개수만큼 총 가격을 보여준다.
영화 선택 기능
좌석 선택 기능
선택한 좌석 개수와 가격 표시 기능
localStorage에서 가져와 새로고침해도 유지되는 기능
요소를 회전시켰을 때 원근감이 느껴도록 하려면 rotate
와 perspective
를 함께 사용해야 한다.
영화관 스크린이 실제로 벽에 붙어 있는 것 같은 효과를 주기 위해 회전 효과가 필요했는데 rotateX
뿐만 아니라, 다음처럼 스크린을 감싸는 부모 요소에 perspective
라는 프로퍼티를 추가해줘야 했다.
그 이유는 perspective
가 원근감을 결정하기 때문!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<style>
body {
background-color: #242333;
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
margin: 0;
}
.container {
perspective: 100px;
perspective: 1000px;
}
.screen {
width: 200px;
height: 80px;
background-color: white;
box-shadow: 0 3px 10px rgba(255, 255, 255, 0.7);
}
.screen:hover {
transition: all 3s ease-out;
transform: rotateX(-180deg);
}
</style>
<title>Document</title>
</head>
<body>
<div class="container">
<div class="screen"></div>
</div>
</body>
</html>
100px
1000px
해당 좌석에 커서를 올렸을 때, 클릭하면 해당 좌석을 선택할 수 있다는 것을 시각적으로 표현해 주기 위해 좌석의 크기가 미세하게 커지도록 구현해야 했다.
이 부분은 transform
과 scale
로 구현할 수 있었다.
transform: scale({배수})
이미 예매된 좌석(occupied)이 아닌 좌석에 커서를 올렸을 때 좌석의 크기가 1.2배로 확대된다.
.seat:not(.occupied):hover {
cursor: pointer;
transform: scale(1.2);
}
예매 가능한 좌석을 클릭하면 하늘색을 색상을 변경해야 했는데, 이는 contains
와 toggle
의 조합으로 구현했다.
해당 노드에 해당 클래스가 있는지 확인하기 위한 메서드다.
<div class="sample">sample div</div>
const div = document.querySelector('.sample');
if(div.classList.contains('sample')) { // true 리턴
console.log('샘플 클래스 보유');
}
if(div.classList.contains('not-sample')) { // false 리턴
console.log('샘플 클래스 미보유');
}
해당 노드에 해당 클래스가 있다면 제거하고 없다면 추가하는 메서드다.
<div class="sample">sample div</div>
const div = document.querySelector('.sample');
if(div.classList.contains('sample')){
div.classList.toggle('selected'); // selected가 없다면 추가하고 있다면 제거한다.
}
container
에 click
이벤트 리스너를 달고 클릭한 요소가 좌석이고(contains(’seat’)), 이미 예매된 좌석이 아닌지(!contains(’occupied’)) 확인한다.
위 조건을 통과하면서 selected
가 없다면(빈 좌석 선택) selected
를 넣어주고, selected
가 있다면(좌석 선택 해제) selected
를 제거한다.
// Seat click event
container.addEventListener('click', (event) => {
// classList로 해당 DOM이 가진 class 목록을 확인할 수 있음
if (event.target.classList.contains('seat') && !event.target.classList.contains('occupied')) {
// toggle로 classList에 해당 클래스명이 있다면 제거하고 없다면 추가
event.target.classList.toggle('selected'); // 좌석 색깔이 파란색으로 변경됨
updateSelectedCount();
}
});
로컬 스토리지에 데이터를 저장하는 작업은 localStorage.setItem
으로 할 수 있다.
localStorage.setItem('keyName', 'values');
원시 값이 아닌 참조 값(배열, 객체 등)을 저장하는 경우에는 JSON
형식으로 바꿔주고 저장하는 것이 좋다.
localStorage.setItem('keyName', JSON.stringify({참조 자료형});
로컬 스토리지에 저장한 데이터를 가져오는 작업은 localStorage.getItem
으로 할 수 있다.
const value = localStorage.getItem('keyName');
JSON 형식으로 저장한 데이터를 가져오기 위해서는 파싱을 해야 한다.
const value = localStorage.getItem(JSON.parse({JSON 형식 데이터}));
계속 예제 많이 풀어보면서 DOM 조작하는 법을 더 익혀야겠다. 아직은 좀 헷갈린다.
완성도가 뛰어나네요. 잘 봤습니다!