返回

点亮编程技能!CSS+Javascript+HTML 日历控件助你化繁为简

前端

构建简约高效的日历控件:掌握 CSS、JavaScript 和 HTML 的艺术

在现代前端开发中,日历控件已成为必不可少的元素。它可以简化日期选择,让预约、预订和数据录入变得更加轻松。在本博客中,我们将深入探讨如何使用 CSS、JavaScript 和 HTML 构建一个简洁高效的日历控件。

1. HTML 骨架:构建基础

首先,我们需要建立日历控件的 HTML 骨架。它将包括一个容器(div),里面包含头部(显示年月和切换按钮)、星期栏(显示星期一到星期日)和日期容器(放置日期单元格)。

<div id="calendar">
  <div class="calendar-header">
    <button class="btn-prev">&lt;</button>
    <span class="calendar-title"></span>
    <button class="btn-next">&gt;</button>
  </div>
  <div class="calendar-week">
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
  </div>
  <div class="calendar-body"></div>
</div>

2. CSS 美化:让日历焕发光彩

接下来,让我们用 CSS 美化日历控件的外观。通过设置字体、颜色、边框和间距等属性,我们可以让日历控件更具美感和易用性。

#calendar {
  width: 300px;
  margin: 0 auto;
  font-family: Arial, sans-serif;
}

.calendar-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px;
  background-color: #f5f5f5;
}

.calendar-title {
  font-size: 1.2rem;
  font-weight: bold;
}

.calendar-week {
  display: flex;
  justify-content: space-between;
  padding: 10px 0;
  background-color: #efefef;
}

.calendar-week span {
  width: 40px;
  height: 40px;
  text-align: center;
  line-height: 40px;
}

.calendar-body {
  display: grid;
  grid-template-columns: repeat(7, 40px);
  grid-gap: 5px;
  padding: 10px;
}

.calendar-body span {
  width: 40px;
  height: 40px;
  text-align: center;
  line-height: 40px;
  border: 1px solid #ccc;
  cursor: pointer;
}

.calendar-body span:hover {
  background-color: #efefef;
}

.calendar-body .active {
  background-color: #007bff;
  color: #fff;
}

3. JavaScript 交互:让日历栩栩如生

最后,我们使用 JavaScript 实现日历控件的交互功能,包括年月切换、日期选择以及高亮显示当前日期等。

// 获取日历控件元素
const calendar = document.getElementById("calendar");

// 获取头部元素
const header = calendar.querySelector(".calendar-header");

// 获取标题元素
const title = header.querySelector(".calendar-title");

// 获取上个月和下个月按钮
const prevBtn = header.querySelector(".btn-prev");
const nextBtn = header.querySelector(".btn-next");

// 获取日期容器元素
const body = calendar.querySelector(".calendar-body");

// 定义当前日期
const today = new Date();

// 定义当前年月
let currentYear = today.getFullYear();
let currentMonth = today.getMonth();

// 定义日期数组
const days = ["日", "一", "二", "三", "四", "五", "六"];

// 渲染日历
function renderCalendar() {
  // 清空日期容器
  body.innerHTML = "";

  // 获取当前月的第一天和最后一天
  const firstDay = new Date(currentYear, currentMonth, 1);
  const lastDay = new Date(currentYear, currentMonth + 1, 0);

  // 获取当前月的第一天是星期几
  const firstDayWeek = firstDay.getDay();

  // 渲染星期栏
  for (let i = 0; i < days.length; i++) {
    const span = document.createElement("span");
    span.innerText = days[i];
    body.appendChild(span);
  }

  // 渲染日期
  let dayCount = 1;
  for (let i = firstDayWeek; i < 7; i++) {
    const span = document.createElement("span");
    span.innerText = "";
    body.appendChild(span);
  }

  while (dayCount <= lastDay.getDate()) {
    const span = document.createElement("span");
    span.innerText = dayCount;
    span.dataset.date = `${currentYear}-${currentMonth + 1}-${dayCount}`;

    // 标记今天
    if (dayCount === today.getDate() && currentMonth === today.getMonth() && currentYear === today.getFullYear()) {
      span.classList.add("active");
    }

    body.appendChild(span);
    dayCount++;
  }

  // 渲染下个月的天数
  let nextMonthDayCount = 1;
  while (body.children.length < 42) {
    const span = document.createElement("span");
    span.innerText = nextMonthDayCount;
    span.dataset.date = `${currentYear}-${currentMonth + 2}-${nextMonthDayCount}`;
    body.appendChild(span);
    nextMonthDayCount++;
  }

  // 更新标题
  title.innerText = `${currentYear}${currentMonth + 1}月`;
}

// 上个月
prevBtn.addEventListener("click", () => {
  currentMonth--;
  if (currentMonth < 0) {
    currentMonth = 11;
    currentYear--;
  }
  renderCalendar();
});

// 下个月
nextBtn.addEventListener("click", () => {
  currentMonth++;
  if (currentMonth > 11) {
    currentMonth = 0;
    currentYear++;
  }
  renderCalendar();
});

// 日期选择
body.addEventListener("click", (e) => {
  const target = e.target;
  if (target.tagName === "SPAN" && target.dataset.date) {
    const [year, month, day] = target.dataset.date.split("-");

    // 触发日期选择事件
    const event = new CustomEvent("dateSelected", {
      detail: {
        year: parseInt(year),
        month: parseInt(month) - 1,
        day: parseInt(day),
      },
    });
    calendar.dispatchEvent(event);

    // 标记选中的日期
    const activeSpan = calendar.querySelector(".calendar-body .active");
    if (activeSpan) {
      activeSpan.classList.remove("active");
    }
    target.classList.add("active");
  }
});

// 初始化日历
renderCalendar();

结论

通过将 HTML、CSS 和 JavaScript 结合起来,我们成功构建了一个简洁高效的日历控件。它不仅外观美观,而且功能强大,可以满足各种日期选择需求。本文提供了详细的步骤和代码示例,帮助你轻松上手。

常见问题解答

  1. 如何自定义日历控件的外观?

    • 自定义 CSS 代码即可调整字体、颜色、大小、边框等样式。
  2. 如何处理日期选择事件?

    • 添加事件监听器到日历控件,并在日期被选择时触发自定义事件,可以获取所选日期的信息。
  3. 日历控件可以显示多个月份吗?

    • 可以,修改渲染逻辑,显示相邻月份的天数。
  4. 如何禁用特定日期?

    • 添加额外的 CSS 类或 JavaScript 逻辑,禁用特定日期单元格。
  5. 日历控件可以与其他库集成吗?

    • 是的,可以与 Moment.js 或 jQuery UI 等库集成,以增强功能。