如何使用 HTML、CSS、JavaScript 和 Firebase 构建活动预订应用程序?

2025-06-11

如何使用 HTML、CSS、JavaScript 和 Firebase 构建活动预订应用程序?

最初发布在我的博客上

在本教程中,我们将使用 HTML、CSS、JavaScript 和 Firebase 构建一个活动预订应用程序。

规划我们的应用程序

我们不会构建一个包含所有功能的完整活动预订应用。在一个教程中涵盖所有内容并不合适,我只是想让内容简单易懂,或许身份验证部分会另写一篇文章来介绍。

因此,我们的活动预订应用程序将具有以下功能:

  • 用户可以创建一个事件并将其存储到 Firestore。
  • 用户可以实时获取所有事件。
  • 用户可以预订活动。
  • 用户不能多次预订同一活动。

现在,我们知道我们的应用程序会是什么样子,让我们在下一部分开始构建它。

标记

我们的 HTML 文件相对简单。我们将在header标签中保存导航栏和最新事件。

  • index.html
<body>
    <header id="home">
      <nav class="navbar">
        <h1>Eventic</h1>
        <ul>
            <li><a href="#home">Home</a></li>
            <li><a href="#events">Events</a></li>
            <li><a href="#add-event">New Event</a></li>
        </ul>
      </nav>
      <div class="welcome-event"></div>
    </header>
    <main>
        <section id="events">
            <h1 class="section-title">Events</h1>
            <div class="events-container"></div>
        </section>
        <section id="add-event">
            <h1 class="section-title">New Event</h1>
            <form class="form">
                <input type="text" id="name" placeholder="Name">
                <input type="number" id="attendee" placeholder="Attendees">
                <textarea id="description" cols="30" rows="10" placeholder="Description..."></textarea>
                <select id="status">
                    <option value="0">Free</option>
                    <option value="1">Paid</option>
                </select>
                <button class="btn btn-primary">Save</button>
            </form>
        </section>
    </main>
Enter fullscreen mode Exit fullscreen mode

接下来,main标签将包装事件列表和使我们能够创建新事件的表单。

这些事件稍后将在 JavaScript 的帮助下显示出来。

  • index.html
<script src="https://www.gstatic.com/firebasejs/7.9.1/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.9.1/firebase-firestore.js"></script>

<script>
  // Your web app's Firebase configuration
  var firebaseConfig = {
    apiKey: "xxxxxxxxxxxxxxxxxxxxxxxxx",
    authDomain: "xxxxxxxxxxxxxxxxxxxxxxxx",
    databaseURL: "xxxxxxxxxxxxxxxxxxxxxxxxx",
    projectId: "xxxxxxxxxxxxxxxxxxxxxxxxx",
    storageBucket: "xxxxxxxxxxxxxxxxxxxxxxxxx",
    messagingSenderId: "xxxxxxxxxxxxxxxxxxxxxxxxx",
    appId: "xxxxxxxxxxxxxxxxxxxxxxxxx"
  };
  // Initialize Firebase
  firebase.initializeApp(firebaseConfig);
  const db = firebase.firestore()
</script>

<script src="db.js"></script>
<script src="app.js"></script>

</body>
</html>
Enter fullscreen mode Exit fullscreen mode

接下来,我们需要将我们的应用程序连接到Firebase以便能够存储我们的数据。

要获得这些凭据,您需要在Firebase 控制台中创建一个新的应用。项目创建完成后,点击</>IOS 和 Android 图标旁边的代码图标来注册您的应用。

现在,要生成凭据,您必须注册应用程序的名称。
最后,像我在这里做的那样,将凭据放入 HTML 文件中。

接下来,复制第一个script标签并更改firebase-app.js为,firebase-firestore.js因为我们将在此项目中使用 Firestore。

然后,firebase使用配置进行初始化并声明一个db稍后将用于与 Firebase 交互的变量。

现在,我们有了标记并成功将我们的项目链接到 Firebase,让我们在下一部分开始设置它的样式。

造型

CSS 文件有点长,因此我不会在这篇文章中涵盖所有内容,我只会重点介绍最重要的部分。不过不用担心,您可以在文章末尾找到源代码。

像往常一样,我们首先导入字体并进行一些重置以防止默认行为。

  • style.css
@import url('https://fonts.googleapis.com/css?family=Nunito:400,700&display=swap');

*,
*::after,
*::before {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

html {
    --primary-color:#e74c3c;
    --secondary-color:#222;
    --tertiary-color:#333;
    --light-color: #fff;
    scroll-behavior: smooth; 
}

body {
    background-color: #1f1f1f;
    font-family: 'Nunito', sans-serif;
    font-size: 1rem;
    color: var(--light-color);
    line-height: 1.6;
}
Enter fullscreen mode Exit fullscreen mode

接下来,我们使用 CSS 变量来存储颜色,并将其设置scroll-behaviorsmooth当用户点击导航栏链接时产生良好的滚动效果。

不过,请注意scroll-behavior,并非所有浏览器都支持它。您仍然可以在这里处理浏览器兼容性问题

  • style.css
nav {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0.5rem 2.5rem;
    z-index: 100;
    width: 100%;
    transition: background 0.3s;
    position: fixed;
    top: 0;
    left: 0;
}

nav ul {
    display: flex;
    list-style: none;
}

nav li:not(:last-child), .welcome-event div span {
    margin-right: 1.5rem;
}
Enter fullscreen mode Exit fullscreen mode

对于导航栏,默认情况下,背景是透明的,为了更好的可用性,当用户开始滚动时它会发生变化。

我们的活动预订应用程序开始成形,现在,让我们开始实施 Firebase 并将我们的应用程序连接到 Firestore。

出色的

与 Firebase 交互

Firebase是一个为我们处理与后端相关的所有事务的平台,我们唯一要做的就是将我们的应用程序连接到它并开始使用数据库或其他服务。

Firestore是一个 NoSQL 数据库,它是非关系型的,使用文档、集合等来创建数据库。

现在,让我们连接到 Firestore 并创建我们的第一个数据库。

获取事件

db在本教程的前面,我们在 HTML 部分声明了一个变量。现在,让我们使用该变量将我们的应用连接到 Firestore。

我会将与数据库相关的所有内容放在db.js文件中,以获得更清晰的结构。

  • db.js
db.collection('events').onSnapshot(snapshot => {
    // Handle the latest event
    const newestEvent = snapshot.docChanges()[0].doc.data()
    const id = snapshot.docChanges()[0].doc.id
    showLatestEvent(newestEvent, id);

    // delete the latest event element
    snapshot.docChanges().shift()

    snapshot.docChanges().forEach(event => {
        showEvents(event.doc.data(), event.doc.id)
    });
})
Enter fullscreen mode Exit fullscreen mode

在 的帮助下db,我们现在可以访问我们的集合events。它只是我们数据库的名称,如果它不存在,Firestore 会为我们动态创建它。

集合对象有一个非常方便的方法,叫做onSnapshot()。它有助于实时监听数据库,这意味着,每当数据库发生变化时,它都会做出反应并实时返回变化。

魔法

onSnapshot()方法还能帮助我们访问文档(我们的数据)。现在,我们可以提取最新事件并将其显示在标题上。在循环遍历事件数组之前,删除最新事件,这样就不再显示它了。

现在,为了在 UI 上显示事件,我们必须调用所需的函数showLatestEvent()showEvents()然后将事件和 ID 作为参数传递给它们。

现在我们可以从 Firestore 获取事件了,但是仍然没有事件可以显示。让我们将第一个事件存储在数据库中。

创建活动

要获取用户输入的值,我们必须首先选择form标签并使用它来选择每个输入的 ID 并提取输入的值。

  • db.js
const addNewEvent = () => {
  const event = {
    name: form.name.value,
    attendee: form.attendee.value,
    booked: 0,
    description: form.description.value,
    status: parseInt(form.status.value, 10)
  }
    db.collection('events').add(event)
    .then(() => {
    // Reset the form values
    form.name.value = "",
    form.attendee.value = "",
    form.description.value = "",
    form.status.value = ""

    alert('Your event has been successfully saved')
    })
    .catch(err => console.log(err))
}
Enter fullscreen mode Exit fullscreen mode

db变量(记住它是 的引用firebase.firestore())还有另一种方法可以将数据保存到 Firestore,即save()函数。这是一个承诺,一旦完成,我们现在可以重置表单的值并向用户显示成功消息。

现在,让我们继续处理用户想要预订活动的情况。

预订活动

正如我之前所说,我们无法检查用户是否经过身份验证,因此,他可能会多次预订活动。

因此,为了解决这个问题,我将使用localStorage防止重复预订的方法。

  • db.js
let bookedEvents = [];

const bookEvent = (booked, id) => {
  const getBookedEvents = localStorage.getItem('booked-events');

    if (getBookedEvents) {
     bookedEvents = JSON.parse(localStorage.getItem('booked-events'));
      if(bookedEvents.includes(id)) {
        alert('Seems like you have already booked this event') 
      } 
      else {
        saveBooking(booked, id)
     }
    } 
    else {
        saveBooking(booked, id)
    }
};

const saveBooking = (booked, id) => {
    bookedEvents.push(id);
    localStorage.setItem('booked-events', JSON.stringify(bookedEvents));

    const data = { booked: booked +1 }
    db.collection('events').doc(id).update(data)
    .then(() => alert('Event successfully booked'))
    .catch(err => console.log(err))
}
Enter fullscreen mode Exit fullscreen mode

正如您所见,我们首先检查活动 ID 是否存储在 localStorage 中。如果是,则用户无法再次预订同一活动;否则,用户可以预订该活动。

为了更新预订计数器,我们再次使用db来更新 Firestore 上的事件。

文件db.js现已完成,因此,让我们进入最后一部分并将我们的项目连接到db.js

使用 JavaScript 显示和更新数据

像往常一样,我们首先选择所需的元素。

const eventsContainer = document.querySelector('.events-container')
const nav = document.querySelector('nav')
const welcomeEvent = document.querySelector('.welcome-event')
const form = document.querySelector('.form')

const showEvents = (event, id) => {
  const {name, attendee, status, description, booked} = event

  const eventStatus = status === 0 ? 'free': 'paid'
  const output = `
        <div class="card">
          <div class="card--details">
            <div>
              <h1>${name}</h1>
              <span>${attendee - booked} attendees</span>
            </div>
            <span class="card--details-ribbon ribbon-${eventStatus}">
                ${eventStatus}
            </span>
             <p>${description}</p>
            <button onclick="bookEvent(${booked} ,'${id}')" class="btn btn-tertiary">Book</button>
          </div>
        </div>
        `
    eventsContainer.innerHTML += output;
}
Enter fullscreen mode Exit fullscreen mode

在本文前面,我们将从文件showEvents()中的 Firestore 中获取的事件作为参数传递给了函数db.js

现在,我们可以提取事件对象中保存的值并显示它。当用户点击按钮预订活动时,我们将调用该bookEvent()函数来处理它。

const showLatestEvent = (latestEvent, id) => {

  const {name, attendee, status, description, booked} = latestEvent 
  // Get the first event
    welcomeEvent.innerHTML = `
    <h1>${name}</h1>
    <p>${description.length >= 100 ? `${description.substring(0, 100)}...` : description}</p>
    <div>
      <span>Attendees: ${attendee - booked}</span>
      <span>Status: ${status === 0 ? 'free': 'paid'}</span>
     </div>
     <button onclick="bookEvent(${booked} ,'${id}')" class="btn btn-tertiary">Book</button>
    `
}

form.addEventListener('submit', e => {
  e.preventDefault()
  addNewEvent()
})

window.onscroll = () =>  {
  if (document.body.scrollTop > 20 || document.documentElement.scrollTop > 20) {
    nav.style.background = 'var(--tertiary-color)';
    nav.style.boxShadow = '0 10px 42px rgba(25,17,34,.1)';
  } else {
    nav.style.background = 'none';
    nav.style.boxShadow = 'none';
  }
}
Enter fullscreen mode Exit fullscreen mode

如您所见,该showLatestEvent()方法与非常相似showEvents(),与用于显示事件的元素不同。

并且,当描述有点长时,我们会用它substring()来截断该值。

接下来,我们监听form元素来处理提交事件并将其存储到 Firestore 中addNewEvent()

为了让一切看起来美观,当用户滚动时,我们会在导航栏上添加背景颜色和框阴影。

通过这一改变,我们现在有了使用 JavaScript 和 Firebase 的活动预订应用程序。

话虽如此,感谢您阅读这篇文章。

您可以在此处实时查看或在此处找到源代码

鏂囩珷鏉ユ簮锛�https://dev.to/ibrahima92/how-to-build-an-event-booking-app-using-html-css-javascript-and-firebase-2k0h
PREV
开发者营销:非传统指南
NEXT
成为一名程序员并不需要 MacBook