基于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'); }); });
逻辑说明
- 状态跟踪:用
clickCount变量记录点击次数,通过奇偶判断执行不同逻辑 - 奇数次点击:清空所有已选中的类,给当前点击的日期添加起始标记
firstClick - 偶数次点击:将临时高亮的
selected日期转为永久选中的reserved状态 - hover优化:修复了原代码中起始日期在hover日期之后时无法反向选中的问题,自动取索引的最小值和最大值确定范围
内容的提问来源于stack exchange,提问作者user3270967
相关产品推荐
相关产品推荐

