製作一個電影定位動態表格 成品:
成品網址
成品功能: 最上方處可以選擇電影 可以選取尚未被占走(occupied)的位置 並且加總最後選取幾個位置以及消費總金額 HTML 下拉式電影選單 標示座位狀態的li
六排座位區的呈現(有些空的有些被占走) 標示總共買了幾個位置以及總消費金額 上 CSS 之前的 HTML:
程式碼: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 <body > <div class ="movie-container" > <label > Pick a movie</label > <select id ="movie" > <option value ="10" > Avengers:Endgame ($10)</option > <option value ="12" > Joker ($12)</option > <option value ="8" > Toy Story 4 ($8)</option > <option value ="9" > The Lion King ($9)</option > </select > </div > <ul class ="showcase" > <li > <div class ="seat" > </div > <small > N/A</small > </li > <li > <div class ="seat selected" > </div > <small > Selected</small > </li > <li > <div class ="seat occupied" > </div > <small > Occupied</small > </li > </ul > <div class ="container" > <div class ="screen" > </div > <div class ="row" > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > </div > <div class ="row" > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat occupied" > </div > <div class ="seat occupied" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > </div > <div class ="row" > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat occupied" > </div > <div class ="seat occupied" > </div > </div > <div class ="row" > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > </div > <div class ="row" > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat occupied" > </div > <div class ="seat occupied" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > </div > <div class ="row" > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat" > </div > <div class ="seat occupied" > </div > <div class ="seat occupied" > </div > <div class ="seat occupied" > </div > <div class ="seat" > </div > </div > </div > <p class ="text" > You have selected <span id ="conunt" > 0</span > seat for a price of <span id ="total" > $0</span > </p > <script src ="script.js" > </script > </body >
CSS: 字體輸出 引入字體的部分要先點選你要的字體粗細大小後,點擊右上角綠色框框會跳出右邊視窗告訴你選了那些字體大小的選項後,點選下方紅框框處的@import 輸出成網址就可以使用瞜!
CSS 設置好的樣式
程式碼 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 @import url('https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,100;0,300;0,400;0,700;0,900;1,100;1,300;1,400;1,700;1,900&display=swap' );* { box-sizing : border-box; } body { background-color : #242333 ; display : flex; flex-direction : column; color : #fff ; align-items : center; justify-content : center; height : 100vh ; font-family : 'Lato' , sans-serif, ; margin : 0 ; } .movie-container select { background-color : #fff ; border : 0 ; border-radius : 5px ; font-size : 14px ; margin-left : 10px ; padding : 5px 15px 5px 15px ; -moz-appearance: none; -webkit-appearance: none; appearance:none; } .container { perspective : 1000px ; margin-bottom : 30px ; } .seat { background-color : #444451 ; height : 12px ; width : 15px ; margin : 3px ; border-top-left-radius : 10px ; border-top-right-radius : 10px ; } .seat .selected { background-color : #6feaf6 ; } .seat .occupied { background-color : #fff ; } .seat :nth-of-type (2 ) { margin-right : 18px ; } .seat :nth-last-of-type (2 ) { margin-left : 18px ; } .seat :not (.occupied ):hover { cursor : pointer; transform : scale (1.2 ); } .showcase .seat :not (.occupied ):hover { cursor : default; transform : none; } .showcase { background-color : rgba (0 , 0 , 0 , 0.1 ); padding : 5px 10px ; border-radius : 5px ; color : #777 ; list-style-type : none; display : flex; justify-content : space-between; } .showcase li { display : flex; align-items : center; justify-content : center; margin : 10px ; } .showcasse li small { margin-left : 2px ; } .row { display : flex; } .screen { background-color : #fff ; height : 70px ; width : 100% ; margin : 15px 0 ; transform : rotateX (-45deg ); box-shadow : 0 3px 10pc rgba (255 , 255 , 255 , 0.7 ); } p .text { margin : 5px 0 ; } p .text span { color : #6feaf6 ; }
小補充:
appearance
-moz-appearance
-webkit-appearance
根據不同作業系統使用的套件 MDN
perspective 透視感 立體感 MDN
rotateX() 以 X 為軸心旋轉 MDN
:nth-of-type 選取第()個元素 MDN
rgba(red 值, green 值, blue 值, alpha 值)- alpha 值代表透明度
JS: JS 主要實現幾個部分:
處理點擊座椅會有藍色特效再次點擊會關閉特效
電影選擇事件(下拉式選單)觸發下面兩個 function:
setMovieData()
會處理下拉式選單選到的電影的 Index 號碼以及價錢並且儲存在 localstorage 上updateSelectedCount()
會因應選取的電影票價(value)去改變 消費總金額1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 const container = document .querySelector('.container' );const seats = document .querySelectorAll('.row .seat:not(.occupied' );const count = document .getElementById('count' );const total = document .getElementById('total' );const movieSelect = document .getElementById('movie' );populateUI(); let ticketPrice = +movieSelect.value;function setMovieData (movieIndex, moviePrice ) { localStorage .setItem('selectedMovieIndex' , movieIndex); localStorage .setItem('selectedMoviePrice' , moviePrice); } function updateSelectedCount ( ) { const selectedSeats = document .querySelectorAll('.row .seat.selected' ); const seatsIndex = [...selectedSeats].map(seat => [...seats].indexOf(seat)); localStorage .setItem('selectedSeats' , JSON .stringify(seatsIndex)); const selectedSeatsCount = selectedSeats.length; count.innerText = selectedSeatsCount; total.innerText = selectedSeatsCount * ticketPrice; } function populateUI ( ) { const selectedSeats = JSON .parse(localStorage .getItem('selectedSeats' )); if (selectedSeats !== null && selectedSeats.length > 0 ) { seats.forEach((seat, index ) => { if (selectedSeats.indexOf(index) > -1 ) { seat.classList.add('selected' ); } }); } const selectedMovieIndex = localStorage .getItem('selectedMovieIndex' ); if (selectedMovieIndex !== null ) { movieSelect.selectedIndex = selectedMovieIndex; } } movieSelect.addEventListener('change' , e => { ticketPrice = +e.target.value; setMovieData(e.target.selectedIndex, e.target.value); updateSelectedCount(); }) container.addEventListener('click' , e => { if (e.target.classList.contains('seat' ) && !e.target.classList.contains('occupied' )) { e.target.classList.toggle('selected' ); updateSelectedCount(); } }) updateSelectedCount();
小補充:
Spread syntax (…) MDN
selectedIndex MDN
localStorage MDN
change 事件