当前位置:首页 > JavaScript

js实现双日历

2026-02-03 06:19:31JavaScript

实现双日历的基础结构

使用HTML创建两个日历容器,分别用于显示起始日期和结束日期。CSS确保两个日历并排显示,样式保持一致。

<div class="calendar-container">
  <div id="calendar-start"></div>
  <div id="calendar-end"></div>
</div>
.calendar-container {
  display: flex;
  gap: 20px;
}
#calendar-start,
#calendar-end {
  width: 300px;
  border: 1px solid #ddd;
  padding: 10px;
}

动态生成日历逻辑

通过JavaScript生成单月日历,支持切换月份。核心逻辑包括计算月份天数、渲染日期格子,并绑定事件处理函数。

js实现双日历

function generateCalendar(containerId, year, month) {
  const container = document.getElementById(containerId);
  const daysInMonth = new Date(year, month + 1, 0).getDate();
  const firstDay = new Date(year, month, 1).getDay();

  let html = `<div class="header">${year}年${month + 1}月</div>`;
  html += '<div class="days-grid">';

  // 填充空白格子(月初偏移)
  for (let i = 0; i < firstDay; i++) {
    html += '<div class="day empty"></div>';
  }

  // 填充日期格子
  for (let day = 1; day <= daysInMonth; day++) {
    html += `<div class="day" data-day="${day}">${day}</div>`;
  }

  container.innerHTML = html;
}

双日历联动与日期选择

初始化两个日历并实现联动逻辑:选择起始日期后自动聚焦结束日期日历,且结束日期不得早于起始日期。

js实现双日历

let startDate = null;
let endDate = null;

function initDualCalendar() {
  const now = new Date();
  generateCalendar('calendar-start', now.getFullYear(), now.getMonth());
  generateCalendar('calendar-end', now.getFullYear(), now.getMonth() + 1);

  // 绑定日期点击事件
  document.querySelectorAll('#calendar-start .day').forEach(day => {
    day.addEventListener('click', () => {
      startDate = new Date(now.getFullYear(), now.getMonth(), parseInt(day.dataset.day));
      updateSelection('calendar-start', day);
    });
  });

  document.querySelectorAll('#calendar-end .day').forEach(day => {
    day.addEventListener('click', () => {
      if (!startDate) return;
      const selectedDate = new Date(now.getFullYear(), now.getMonth() + 1, parseInt(day.dataset.day));
      if (selectedDate >= startDate) {
        endDate = selectedDate;
        updateSelection('calendar-end', day);
      }
    });
  });
}

function updateSelection(calendarId, selectedElement) {
  // 清除旧选中状态
  document.querySelectorAll(`#${calendarId} .day.selected`).forEach(el => {
    el.classList.remove('selected');
  });
  selectedElement.classList.add('selected');
}

月份切换功能

添加按钮支持向前/向后切换月份,并同步更新两个日历的显示。

function addMonthSwitchers() {
  const startPrev = document.createElement('button');
  startPrev.textContent = '<';
  startPrev.addEventListener('click', () => switchMonth('calendar-start', -1));

  const startNext = document.createElement('button');
  startNext.textContent = '>';
  startNext.addEventListener('click', () => switchMonth('calendar-start', 1));

  document.getElementById('calendar-start').prepend(startPrev, startNext);
}

function switchMonth(calendarId, offset) {
  const header = document.querySelector(`#${calendarId} .header`);
  const [year, month] = header.textContent.match(/\d+/g).map(Number);
  const newMonth = month - 1 + offset;
  generateCalendar(calendarId, newMonth < 0 ? year - 1 : year, (newMonth + 12) % 12);
}

样式优化与交互反馈

通过CSS增强视觉反馈,例如高亮选中日期、禁用无效日期。

.day {
  padding: 5px;
  cursor: pointer;
}
.day.selected {
  background-color: #007bff;
  color: white;
}
.day.disabled {
  color: #ccc;
  cursor: not-allowed;
}

标签: 双日js
分享给朋友:

相关文章

vue.js实现轮播

vue.js实现轮播

Vue.js 实现轮播功能 使用第三方库(推荐) Vue.js 生态中有许多成熟的轮播组件库,例如 vue-awesome-swiper 或 swiper,它们功能丰富且易于集成。 安装 swipe…

js实现抽奖

js实现抽奖

实现抽奖功能的基本思路 抽奖功能的核心是随机选择奖项并展示结果。可以通过数组存储奖项,利用随机数生成索引,最后通过动画增强用户体验。 准备奖项数据 定义一个数组存储奖项信息,每个奖项可以包含名称、图…

js实现点击显示和隐藏

js实现点击显示和隐藏

实现点击显示和隐藏的JavaScript方法 使用classList.toggle切换类名 通过添加/移除CSS类控制元素的显示与隐藏,需提前在CSS中定义隐藏样式(如display: none)。…

js实现变形

js实现变形

使用 CSS 和 JavaScript 实现元素变形 在 JavaScript 中实现变形效果通常结合 CSS 的 transform 属性,通过动态修改该属性实现元素的旋转、缩放、倾斜或平移。 基…

js实现下拉刷新

js实现下拉刷新

监听触摸事件 通过监听 touchstart、touchmove 和 touchend 事件来检测用户下拉手势。记录触摸起始位置和移动距离。 let startY = 0; let currentY…

js分页实现

js分页实现

分页的基本原理 分页的核心是通过计算当前页码和数据偏移量,从服务器或本地数据中截取对应范围的数据进行展示。通常需要以下参数:当前页码(currentPage)、每页条数(pageSize)、总数据量(…