前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >亲自上手,用原生 JavaScript 打造简易电影选座系统

亲自上手,用原生 JavaScript 打造简易电影选座系统

作者头像
前端达人
发布2024-06-14 14:16:56
720
发布2024-06-14 14:16:56
举报
文章被收录于专栏:前端达人前端达人
大家有没有在使用App选电影票的经历呢?我们今天就来实现一个简易版的电影选座系统。这个系统的功能包括:
  • 显示电影列表,并且可以选择不同的电影
  • 展示座位图,并且可以选择座位
  • 实时计算和显示已选座位数量和总价
  • 使用本地缓存保存用户的选择状态,并在页面刷新后保持状态

案例展示

我们来看一下最终实现的效果,如图所示:

项目实现思路

接下来我们需要按照这个思路制作我们的项目,我会一一进行详细介绍。

  • 创建基础HTML结构:定义选择电影的下拉菜单和座位布局。
  • 添加CSS样式:美化页面,使其更符合实际的电影院选座系统。
  • 实现JavaScript逻辑:处理座位选择、电影选择、价格计算和状态保存等功能。
  • 本地存储:使用浏览器的localStorage保存用户选择的电影和座位信息,在页面刷新时重新加载这些信息。

创建基础HTML结构

首先,我们需要一个基础的HTML结构来展示电影列表和座位布局。这一步主要是定义页面的基本框架,让用户能够看到选择电影和座位的界面。

a. 确定页面的主要部分

一个简单的电影选座系统主要包含以下几个部分:

  • 电影选择区域
  • 座位展示区域
  • 已选座位信息展示区域

HTML代码

以下是完整的HTML代码,并附有注释帮助理解:

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <link rel="stylesheet" href="style.css">
  <title>Movie Seat Booking</title>
</head>
<body>
  <!-- 电影选择区域 -->
  <div class="movie-container">
    <label for="movie">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>

  <!-- 已选座位信息展示区域 -->
  <p class="text">
    You have selected <span id="count">0</span> seats for a price of $<span id="total">0</span>
  </p>

  <script src="script.js"></script>
</body>
</html>

添加CSS样式

为了使我们的页面更美观且易于使用,我们需要一些CSS样式。样式的目的是让页面看起来更像电影院的座位选择界面。

代码语言:javascript
复制
@import url('https://fonts.googleapis.com/css?family=Lato&display=swap');

* {
  box-sizing: border-box;
}

body {
  background-color: #242333;
  color: #fff;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100vh;
  font-family: 'Lato', sans-serif;
  margin: 0;
}

.movie-container {
  margin: 20px 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: scale(1);
}

.showcase {
  background: 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: 0 10px;
}

.showcase 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 10px rgba(255, 255, 255, 0.7);
}

p.text {
  margin: 5px 0;
}

p.text span {
  color: #6feaf6;
}

JavaScript功能实现

JavaScript是实现页面交互的核心部分,通过JavaScript我们可以实现座位选择、电影选择、价格计算和状态保存等功能。以下是详细的实现思路:

a. 获取DOM元素

首先,我们需要获取页面上的一些重要元素,以便后续操作。

代码语言:javascript
复制
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');

b. 初始化票价和电影数据

通过读取电影选择框的值来初始化票价。

代码语言:javascript
复制
let ticketPrice = +movieSelect.value;

c. 事件监听

为电影选择框和座位添加事件监听器,用户选择电影或座位时触发相应的处理逻辑。

代码语言:javascript
复制
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();
  }
});

d. 更新选中座位数和总价

当用户选择或取消选择座位时,更新座位数量和总价,并将选中状态保存到本地存储。

代码语言:javascript
复制
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;
}

e. 本地存储

为了保持用户的选择状态,我们使用localStorage来保存和读取数据。

保存选中电影和座位的信息:

代码语言:javascript
复制
function setMovieData(movieIndex, moviePrice) {
  localStorage.setItem('selectedMovieIndex', movieIndex);
  localStorage.setItem('selectedMoviePrice', moviePrice);
}

从本地存储中读取数据并更新页面:

代码语言:javascript
复制
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;
  }
}

完整的JS代码

代码语言:javascript
复制
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;
}

// 从本地存储中获取数据并更新UI
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();

通过以上步骤,我们实现了一个基本的电影选座系统,用户可以选择电影和座位,并且在页面刷新后仍然保留之前的选择状态。这一系列的操作将帮助初学者理解如何通过前端技术来实现一个功能完备的小项目。

结束

这就是一个简易的电影选座系统的实现过程啦!你是不是也觉得自己能动手做一个了呢?赶快试试看吧!如果你有任何问题或者改进建议,欢迎在评论区留言哦!希望大家都能学有所成,成为代码大神!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-06-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 前端达人 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 案例展示
  • 项目实现思路
  • 创建基础HTML结构
    • a. 确定页面的主要部分
      • HTML代码
      • 添加CSS样式
      • JavaScript功能实现
        • a. 获取DOM元素
          • b. 初始化票价和电影数据
            • c. 事件监听
              • d. 更新选中座位数和总价
                • e. 本地存储
                  • 完整的JS代码
                  • 结束
                  相关产品与服务
                  对象存储
                  对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档