You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现选择指定年月后展示对应日历,其余内容仅可读不可选?

嘿,这个需求很清晰,我给你整了一套完整的实现方案,包含HTML、CSS和JavaScript,直接就能复用:

实现思路

核心逻辑就是:监听月份和年份选择框的变化,当选中1月 + 2018年时,渲染可交互的完整日历;其他情况渲染只读状态的日历(日期不可点击、样式灰化)。

HTML 结构

先搭好基础的选择器和日历容器:

<div class="calendar-controls">
  <select id="month-select">
    <option value="1">1月</option>
    <option value="2">2月</option>
    <option value="3">3月</option>
    <option value="4">4月</option>
    <option value="5">5月</option>
    <option value="6">6月</option>
    <option value="7">7月</option>
    <option value="8">8月</option>
    <option value="9">9月</option>
    <option value="10">10月</option>
    <option value="11">11月</option>
    <option value="12">12月</option>
  </select>
  <select id="year-select">
    <option value="2017">2017年</option>
    <option value="2018" selected>2018年</option>
    <option value="2019">2019年</option>
    <option value="2020">2020年</option>
  </select>
</div>

<div class="calendar-container" id="calendar-container">
  <div class="calendar-header">
    <div>日</div>
    <div>一</div>
    <div>二</div>
    <div>三</div>
    <div>四</div>
    <div>五</div>
    <div>六</div>
  </div>
  <div class="calendar-days" id="calendar-days"></div>
</div>
CSS 样式

给日历加上基础样式,区分可交互和只读状态:

.calendar-controls {
  margin-bottom: 1rem;
}

.calendar-container {
  max-width: 400px;
  font-family: Arial, sans-serif;
}

.calendar-header {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 5px;
  margin-bottom: 5px;
  font-weight: bold;
  text-align: center;
}

.calendar-days {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 5px;
}

.calendar-day {
  padding: 10px;
  text-align: center;
  border: 1px solid #eee;
  cursor: pointer;
  transition: background-color 0.2s;
}

.calendar-day:hover {
  background-color: #f0f0f0;
}

/* 只读状态样式 */
.readonly-calendar .calendar-day {
  cursor: not-allowed;
  color: #999;
}

.readonly-calendar .calendar-day:hover {
  background-color: transparent;
}

/* 非当月日期样式(可选) */
.calendar-day.other-month {
  color: #ccc;
}
JavaScript 逻辑

实现日历生成和状态控制的核心代码:

const monthSelect = document.getElementById('month-select');
const yearSelect = document.getElementById('year-select');
const calendarDays = document.getElementById('calendar-days');
const calendarContainer = document.getElementById('calendar-container');

// 初始化日历
renderCalendar();

// 监听选择器变化
monthSelect.addEventListener('change', renderCalendar);
yearSelect.addEventListener('change', renderCalendar);

function renderCalendar() {
  const selectedMonth = monthSelect.value; // 1-12
  const selectedYear = yearSelect.value;
  const isInteractive = selectedMonth === '1' && selectedYear === '2018';

  // 设置日历状态
  if (isInteractive) {
    calendarContainer.classList.remove('readonly-calendar');
  } else {
    calendarContainer.classList.add('readonly-calendar');
  }

  // 清空之前的日期
  calendarDays.innerHTML = '';

  // 处理月份转换(JS Date 月份是0-11)
  const jsMonth = parseInt(selectedMonth) - 1;
  const firstDayOfMonth = new Date(selectedYear, jsMonth, 1);
  const lastDayOfMonth = new Date(selectedYear, jsMonth + 1, 0);
  const daysInMonth = lastDayOfMonth.getDate();
  const startWeekDay = firstDayOfMonth.getDay(); // 0=周日,6=周六

  // 填充当月之前的空白日期
  for (let i = 0; i < startWeekDay; i++) {
    const emptyDay = document.createElement('div');
    emptyDay.classList.add('calendar-day', 'other-month');
    calendarDays.appendChild(emptyDay);
  }

  // 填充当月日期
  for (let day = 1; day <= daysInMonth; day++) {
    const dayElement = document.createElement('div');
    dayElement.classList.add('calendar-day');
    dayElement.textContent = day;

    // 只有可交互状态下添加点击事件
    if (isInteractive) {
      dayElement.addEventListener('click', () => {
        alert(`你选中了 ${selectedYear}年${selectedMonth}月${day}日`);
        // 这里可以替换成你的业务逻辑
      });
    }

    calendarDays.appendChild(dayElement);
  }

  // 填充当月之后的空白日期
  const totalCells = startWeekDay + daysInMonth;
  const remainingCells = 42 - totalCells; // 6行*7列=42个格子
  for (let i = 0; i < remainingCells; i++) {
    const emptyDay = document.createElement('div');
    emptyDay.classList.add('calendar-day', 'other-month');
    calendarDays.appendChild(emptyDay);
  }
}
关键说明
  • 当选中1月2018时,日历会移除readonly-calendar类,日期可点击并触发自定义逻辑;其他情况添加该类,日期灰化且不可点击。
  • 日历自动处理了当月前后的空白日期,保证布局整齐(6行固定高度)。
  • 你可以根据需求调整年份范围、日历样式,或者修改点击事件里的业务逻辑。

内容的提问来源于stack exchange,提问作者Parth Makwana

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:01:55