자바스크립트 영화 예매 창 만들기

버건디·2022년 9월 27일
0
post-thumbnail

🔍 완성 화면


🔍 설계도


🔍 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">
    <title>Movie Booking</title>
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Lato:wght@300&display=swap" rel="stylesheet">
    <link rel="stylesheet" href="style.css">
    <script src="main.js"></script>
</head>

<body>
    <div id="container">
        <div class="movieContainer">
            <label for="movie">
                Pick a Movie :
            </label>
            <select name="pickMovie" id="movie">
                <option class="price" value="10">Avengers:Endgame ($10)</option>
                <option class="price" value="12">Joker ($12)</option>
                <option class="price" value="8">Toy Story 4 ($8)</option>
                <option class="price" value="9">The Lion King ($9)</option>
            </select>
        </div>
        <ul class="showcase">
            <li>
                <div class="availableSeat"></div>
                <small class="small">Available Seat</small>
            </li>
            <li>
                <div class="selectedSeatIcon"></div>
                <small class="small">Selected Seat</small>
            </li>
            <li>
                <div class="occupiedSeat"></div>
                <small class="small">Occupied Seat</small>
            </li>
        </ul>

        <div class="seatContainer">
            <div class="screen"></div>
            <div class="row">
                <span class="seat"></span>
                <span class="seat"></span>
                <span class="seat"></span>
                <span class="seat"></span>
                <span class="seat"></span>
                <span class="seat"></span>
                <span class="seat"></span>
                <span class="seat"></span>
            </div>

            <div class="row">
                <span class="seat"></span>
                <span class="seat"></span>
                <span class="seat"></span>
                <span class="seat"></span>
                <span class="occupiedSeat"></span>
                <span class="occupiedSeat"></span>
                <span class="seat"></span>
                <span class="seat"></span>
            </div>

            <div class="row">
                <span class="seat"></span>
                <span class="seat"></span>
                <span class="seat"></span>
                <span class="seat"></span>
                <span class="seat"></span>
                <span class="seat"></span>
                <span class="occupiedSeat"></span>
                <span class="seat"></span>
            </div>

            <div class="row">
                <span class="seat"></span>
                <span class="seat"></span>
                <span class="seat"></span>
                <span class="seat"></span>
                <span class="seat"></span>
                <span class="seat"></span>
                <span class="occupiedSeat"></span>
                <span class="occupiedSeat"></span>
            </div>

            <div class="row">
                <span class="seat"></span>
                <span class="seat"></span>
                <span class="seat"></span>
                <span class="seat"></span>
                <span class="seat"></span>
                <span class="seat"></span>
                <span class="seat"></span>
                <span class="seat"></span>
            </div>

            <div class="row">
                <span class="seat"></span>
                <span class="occupiedSeat"></span>
                <span class="occupiedSeat"></span>
                <span class="seat"></span>
                <span class="seat"></span>
                <span class="seat"></span>
                <span class="occupiedSeat"></span>
                <span class="seat"></span>
            </div>

        </div>

        <p class="text">You have selected <span id="count">0</span> seats for a price of $ <span id="costs">0</span></p>




    </div>
</body>

</html>

📌 label 속성이란 ?

input 요소와 연결지어서 input 창의 유연성을 더 할 수 있는 속성이다.

예를 들어서, input 만 있다면 input 안의 칸을 클릭해야만 input 창이 클릭 되는데, label for 속성을 이용해서 label for '값' 과 input 의 id 를 똑같이 해준다면 label 칸만 클릭하더라도 input 안의 칸이 클릭된다.

여기서도 마찬가지로 label for 안에 movie 를 입력해주었고 select 의 id 값을 movie 와 동일하게 맞춰줌으로써

select 창의 유연성을 더해주었다.

❗️ Pick a movie 를 클릭해도 select 창의 테두리가 파란색으로 변한다 ❗️


📌 select, option 속성이란 ?

HTML 에서 select 는 여러 option들을 선택할 수 있는 메뉴창을 제공한다.

보통 label 과의 연결을 위해서 id 속성을, 서버로 데이터를 전송하기 위해서 name 속성을 사용한다.

그리고 option 들은 본인이 선택 됐을때 사용할 value 값들이 필요하다 .

여기서는 여러 영화 option 중에 한개가 선택 됐을때, 영화 관람 비용을 계산 해야 하므로 value 값들을 각각

영화 비용으로 설정하였다.


🔍 CSS 만들기

body{
    font-family: 'Lato', sans-serif;
    background-color: #242333;
    color: #fff;
    box-sizing: border-box;
}

#container{
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    height: 800px;

}

.movieContainer{
    margin: 20px 0px;
}

.showcase{
    background-color: #777;
    background: rgba(0, 0, 0, 0.1);
    border-radius: 5px;
    display: flex;
    justify-content: center;
    margin: 16px 0;
    padding: 5px 10px;
}

.movieContainer select{
    margin: 10px;
    padding: 5px 15px 5px 15px;
    border-radius: 7px;
    appearance: none;
    border: 0;
}

.movieContainer select option{

   text-align: left;
}

li{
    display: flex;
    justify-content: center;
    align-items: center;
    margin-left: 10px;
}

.small{
    color: #777;
    margin-left: 2px;
}

.showcase .seat:hover{
    cursor: default;
    scale: 1;
}

.showcase .selectedSeat:hover{
    cursor: default;
    scale: 1;
}

.screen{
   background-color: #fff;
   margin: 25px;
   padding: 5px;
   width: 140px;
   height: 80px;
   transform: rotateX(-45deg);
   box-shadow: 0 3px 10px rgb(255 255 255 / 70%);
}

.seat{
    background-color: #444451;
    width: 15px;
    height: 12px;
    margin: 3px;
    border-top-left-radius: 10px;
    border-top-right-radius: 10px;
    cursor: pointer;
}

.availableSeat{
    background-color: #444451;
    width: 15px;
    height: 12px;
    margin: 3px;
    border-top-left-radius: 10px;
    border-top-right-radius: 10px;
    cursor: default;
}

.selectedSeatIcon{
    background-color: #6feaf6;
    width: 15px;
    height: 12px;
    margin: 3px;
    border-top-left-radius: 10px;
    border-top-right-radius: 10px;
    cursor: default;
}

.seat:hover{
    scale: 1.2;
}

.selectedSeat:hover{
    scale: 1.2;
}

.seat:nth-of-type(2){
    margin-right: 18px;
}

.seat:nth-of-type(7){
    margin-left: 18px;
}

.occupiedSeat:nth-of-type(2){
    margin-right: 18px;
}
.occupiedSeat:nth-of-type(7){
    margin-left: 18px;
}

.selectedSeat{
    background-color: #6feaf6;
    width: 15px;
    height: 12px;
    margin: 3px;
    border-top-left-radius: 10px;
    border-top-right-radius: 10px;
    cursor: pointer;
}

.occupiedSeat{
    background-color: #fff;
    width: 15px;
    height: 12px;
    margin: 3px;
    border-top-left-radius: 10px;
    border-top-right-radius: 10px;
}

.row{
    display: flex;
}

.text{
    margin-top: 30px;
    padding: 20px;
}

#count{
    color: #6feaf6;
}

#costs{
    color: #6feaf6;
}

🔍 자바스크립트 변수 설정

document.addEventListener('DOMContentLoaded', () =>{

    // const seat = document.querySelectorAll('.seat') 이런식으로 하면 안됨

    const seatContainer = document.querySelector('.seatContainer');
    
    const movie = document.getElementById('movie'); // 선택할 영화
    let moviePrice = Number(movie.value); // 현재 영화 값

    let count = document.querySelector('#count'); // 인원수
    let costs = document.querySelector('#costs'); // 가격


})

처음에는 클래스명이 seat 인 부분들을 querySelectorAll 을 사용해서 가져오려 했는데 이렇게 하니

이런 not a function 에러가 발생했다.

이유를 검색해보니 저 span 클래스명들은 지금 NodeList 배열안에 여러개가 존재하는 것이므로

만약 저런식으로 클래스명을 가져오려면

   const seat = document.querySelectorAll('.seat')

    seat[0].addEventListener('click', () => {
                ...
    })

이런 식으로 특정한 인덱스 값을 들고와야 했다.

그렇기 때문에 그 상위 클래스인 seatContainer 에서 e.target.className 값을 들고 왔다.

🔍 클릭 이벤트 발생시키기

    //좌석 클릭했을때

    seatContainer.addEventListener('click', (e) => {

        if(e.target.className === 'seat'){
            e.target.className = 'selectedSeat';
        } else if(e.target.className === 'selectedSeat'){
            e.target.className = 'seat';
        }
      
       countSeatPrice();
      
    })

클래스명이 seat 인 좌석을 클릭할때 클래스명을 selectedSeat 으로, 다시 클래스명이 selectedSeat 인 좌석을 클릭할때 클래스명을 seat 으로 변경해주면서 색깔을 바꿔주었다.

🔍 클릭할때 가격과 좌석수 텍스트 변경해주기


    function countSeatPrice(){
        const selectedSeatCount = document.querySelectorAll('.selectedSeat').length;

        count.textContent = selectedSeatCount;
        costs.textContent = selectedSeatCount * moviePrice;
        
    }

이런식으로 selectorAll 을 사용해서 콘솔창에 찍어보면 NodeList 배열이 나오는데, 그 길이를 가져와서

텍스트 창의 값들을 변경해주었다.

🔍 영화 변경할때 그에 맞는 가격 가져오기


    movie.addEventListener('change', (e) => {

        moviePrice = Number(e.target.value);

        countSeatPrice()
        
    })

select 창에서 change 이벤트를 발생시키고 거기 안에 있는 option의 value 값을 가져와서

값을 변경시켜주었다. 그러고 countSeatPrice() 함수를 실행시켜서 텍스트도 그에 맞게 변경해주었다!


🔍 HTML, JS 코드

<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">
    <title>Movie Booking</title>
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Lato:wght@300&display=swap" rel="stylesheet">
    <link rel="stylesheet" href="style.css">
</head>

<body>
    <div id="container">
        <div class="movieContainer">
            <label for="movie">
                Pick a Movie :
            </label>
            <select name="pickMovie" id="movie">
                <option class="price" value="10">Avengers:Endgame ($10)</option>
                <option class="price" value="12">Joker ($12)</option>
                <option class="price" value="8">Toy Story 4 ($8)</option>
                <option class="price" value="9">The Lion King ($9)</option>
            </select>
        </div>
        <ul class="showcase">
            <li>
                <div class="availableSeat"></div>
                <small class="small">Available Seat</small>
            </li>
            <li>
                <div class="selectedSeatIcon"></div>
                <small class="small">Selected Seat</small>
            </li>
            <li>
                <div class="occupiedSeat"></div>
                <small class="small">Occupied Seat</small>
            </li>
        </ul>

        <div class="seatContainer">
            <div class="screen"></div>
            <div class="row">
                <span class="seat"></span>
                <span class="seat"></span>
                <span class="seat"></span>
                <span class="seat"></span>
                <span class="seat"></span>
                <span class="seat"></span>
                <span class="seat"></span>
                <span class="seat"></span>
            </div>

            <div class="row">
                <span class="seat"></span>
                <span class="seat"></span>
                <span class="seat"></span>
                <span class="seat"></span>
                <span class="occupiedSeat"></span>
                <span class="occupiedSeat"></span>
                <span class="seat"></span>
                <span class="seat"></span>
            </div>

            <div class="row">
                <span class="seat"></span>
                <span class="seat"></span>
                <span class="seat"></span>
                <span class="seat"></span>
                <span class="seat"></span>
                <span class="seat"></span>
                <span class="occupiedSeat"></span>
                <span class="seat"></span>
            </div>

            <div class="row">
                <span class="seat"></span>
                <span class="seat"></span>
                <span class="seat"></span>
                <span class="seat"></span>
                <span class="seat"></span>
                <span class="seat"></span>
                <span class="occupiedSeat"></span>
                <span class="occupiedSeat"></span>
            </div>

            <div class="row">
                <span class="seat"></span>
                <span class="seat"></span>
                <span class="seat"></span>
                <span class="seat"></span>
                <span class="seat"></span>
                <span class="seat"></span>
                <span class="seat"></span>
                <span class="seat"></span>
            </div>

            <div class="row">
                <span class="seat"></span>
                <span class="occupiedSeat"></span>
                <span class="occupiedSeat"></span>
                <span class="seat"></span>
                <span class="seat"></span>
                <span class="seat"></span>
                <span class="occupiedSeat"></span>
                <span class="seat"></span>
            </div>

        </div>

        <p class="text">You have selected <span id="count">0</span> seats for a price of $ <span id="costs">0</span></p>




    </div>

    <script>
        document.addEventListener('DOMContentLoaded', () =>{

const seatContainer = document.querySelector('.seatContainer');

const movie = document.getElementById('movie'); // 선택할 영화
let moviePrice = Number(movie.value); // 영화과격 

let count = document.querySelector('#count'); // 인원수
let costs = document.querySelector('#costs'); // 가격

// 선택한 좌석수 텍스트 변경해주기

function countSeatPrice(){
    const selectedSeatCount = document.querySelectorAll('.selectedSeat').length;

    count.textContent = selectedSeatCount;
    costs.textContent = selectedSeatCount * moviePrice;
    
}


//좌석 클릭했을때

seatContainer.addEventListener('click', (e) => {

    if(e.target.className === 'seat'){
        e.target.className = 'selectedSeat';
    } else if(e.target.className === 'selectedSeat'){
        e.target.className = 'seat';
    }

    countSeatPrice();
})

// 영화 변경할때

movie.addEventListener('change', (e) => {

    moviePrice = Number(e.target.value);

    countSeatPrice()
    
})




})
    </script>
</body>

</html>
profile
https://brgndy.me/ 로 옮기는 중입니다 :)

0개의 댓글