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

基于jQuery实现HTML日历的日期范围选择与重置功能求助

日期范围选择日历的重置逻辑实现方案

问题背景

我做了一个支持日期范围选择的HTML日历,但现在没法删除已选中的日期范围。我打算用奇偶点击逻辑来实现:

  • 第1次(奇数次)点击:选择起始日期
  • 第2次(偶数次)点击:确认日期范围
  • 第3次(奇数次)点击:清空所有选中内容,重新选择新的起始日期
  • 第4次(偶数次)点击:确认新的日期范围
  • ……
    自己卡壳了,求建议和帮助。

原代码示例

JavaScript

$(document).ready(function() {
  $('td.day').click(function() {
    if ($("td.firstClick").length == 0) {
      $(this).addClass("firstClick");
    }
  });

  $('td.day').hover(function() {
    if ($("td.firstClick").length == 0) {
      $(this).addClass("selected");
      return;
    }
    
    $(this).addClass("secondClick");
    var tds = $('td.day');
    var firstClick = $("firstClick"); // 缺少类选择器的点
    var firstClickIndex = tds.index(firstClick);
    var currentIndex = tds.index(this);
    tds.filter(function() {
      var idx = tds.index(this);
      return idx >= firstClickIndex && idx <= currentIndex;
    }).addClass("selected")
  }, function() {
    if ($("td.firstClick").length == 0) {
      $(this).removeClass("selected");
      return;
    }

    $(this).removeClass("secondClick");
    var tds = $('td.day');
    var firstClick = $("firstClick"); // 同样缺少类选择器的点
    var firstClickIndex = tds.index(firstClick);
    var currentIndex = tds.index(this);
    tds.filter(function() {
      var idx = tds.index(this);
      return idx >= firstClickIndex && idx <= currentIndex;
    }).removeClass("selected")
  });

  $('table').on('click', 'td.secondClick', function() {
    $('.selected').addClass('reserved');
  });
});

CSS

table {
  border-collapse: collapse;
}
table tr td {
  width: 14%;
}
table tr td:hover {
  cursor: pointer;
}
.firstClick {
  background: green;
}
.selected {
  background: lightgreen;
}
.reserved {
  background: red !important;
}
.secondClick {
  background: green;
}

HTML

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table border="1">
  <tr>
    <td colspan="7"><b>2016</b>
    </td>
  </tr>
  <tr>
    <td colspan="7"><i>November</i>
    </td>
  </tr>
  <tr>
    <th>mon</th>
    <th>tue</th>
    <th>wed</th>
    <th>thu</th>
    <th>fri</th>
    <th>sat</th>
    <th>sun</th>
  </tr>
  <tr>
    <td></td>
    <td class="day">1</td>
    <td class="day">2</td>
    <td class="day">3</td>
    <td class="day">4</td>
    <td class="day">5</td>
    <td class="day">6</td>
  </tr>
  <tr>
    <td class="day">7</td>
    <td class="day">8</td>
    <td class="day">9</td>
    <td class="day">10</td>
    <td class="day">11</td>
    <td class="day">12</td>
    <td class="day">13</td>
  </tr>
  <tr>
    <td class="day">14</td>
    <td class="day">15</td>
    <td class="day">16</td>
    <td class="day">17</td>
    <td class="day">18</td>
    <td class="day">19</td>
    <td class="day">20</td>
  </tr>
  <tr>
    <td class="day">21</td>
    <td class="day">22</td>
    <td class="day">23</td>
    <td class="day">24</td>
    <td class="day">25</td>
    <td class="day">26</td>
    <td class="day">27</td>
  </tr>
  <tr>
    <td class="day">28</td>
    <td class="day">29</td>
    <td class="day">30</td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
  </tr>
</table>

改进方案

原代码存在两个核心问题:选择器语法错误,以及缺少奇偶点击的状态跟踪逻辑。以下是修正后的实现,完全符合预期的奇偶点击规则:

修改后的JavaScript代码

$(document).ready(function() {
  // 计数器跟踪点击次数,初始为0
  let clickCount = 0;
  const $days = $('td.day');

  $days.click(function() {
    clickCount++;
    // 奇数次点击:清空所有选中状态,设置新的起始日期
    if (clickCount % 2 === 1) {
      $days.removeClass('firstClick selected reserved secondClick');
      $(this).addClass('firstClick');
    } 
    // 偶数次点击:确认当前选中的日期范围
    else {
      $('.selected').addClass('reserved');
    }
  });

  $days.hover(function() {
    const $firstClick = $('.firstClick');
    // 无起始日期时,仅高亮当前hover的日期
    if ($firstClick.length === 0) {
      $(this).addClass('selected');
      return;
    }

    const firstIndex = $days.index($firstClick);
    const currentIndex = $days.index(this);
    // 处理起始日期在当前日期之后的反向选择
    const start = Math.min(firstIndex, currentIndex);
    const end = Math.max(firstIndex, currentIndex);

    // 高亮范围内的所有日期
    $days.filter((idx) => idx >= start && idx <= end).addClass('selected');
  }, function() {
    // 离开时移除临时高亮,保留起始日期样式
    $days.removeClass('selected');
    $('.firstClick').addClass('firstClick');
  });
});

逻辑说明

  1. 状态跟踪:用clickCount变量记录点击次数,通过奇偶判断执行不同逻辑
  2. 奇数次点击:清空所有已选中的类,给当前点击的日期添加起始标记firstClick
  3. 偶数次点击:将临时高亮的selected日期转为永久选中的reserved状态
  4. hover优化:修复了原代码中起始日期在hover日期之后时无法反向选中的问题,自动取索引的最小值和最大值确定范围

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 23:45:34