在很多后台管理系统或者数据筛选场景中,我们需要让用户选择一段连续的日期范围,而Bootstrap Datepicker是前端开发中常用的日期选择插件,默认仅支持单日期选择,要实现单日历下的日期范围选择,需要对其事件和配置进行扩展。
实现思路说明
单日历日期范围选择的核心逻辑是记录用户两次点击的日期,第一次点击记为开始日期,第二次点击记为结束日期,两次点击之间高亮显示所有日期。我们需要监听Datepicker的日期选择事件,维护开始日期和结束日期两个状态变量,同时自定义日期渲染逻辑来高亮范围内的日期。
环境准备
首先需要引入Bootstrap和Bootstrap Datepicker的相关资源,确保依赖版本兼容,这里使用稳定版本的资源:
<!-- 引入Bootstrap样式 --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.4.1/dist/css/bootstrap.min.css"> <!-- 引入Bootstrap Datepicker样式 --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-datepicker@1.9.0/dist/css/bootstrap-datepicker.min.css"> <!-- 引入jQuery --> <script src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js"></script> <!-- 引入Bootstrap JS --> <script src="https://cdn.jsdelivr.net/npm/bootstrap@3.4.1/dist/js/bootstrap.min.js"></script> <!-- 引入Bootstrap Datepicker JS --> <script src="https://cdn.jsdelivr.net/npm/bootstrap-datepicker@1.9.0/dist/js/bootstrap-datepicker.min.js"></script> <!-- 引入中文语言包 --> <script src="https://cdn.jsdelivr.net/npm/bootstrap-datepicker@1.9.0/dist/locales/bootstrap-datepicker.zh-CN.min.js"></script>
核心代码实现
HTML结构
创建一个输入框用于触发日期选择器,代码如下:
<div class="container" style="margin-top: 50px;">
<div class="form-group">
<label for="dateRangePicker">选择日期范围:</label>
<input type="text" class="form-control" id="dateRangePicker" placeholder="点击选择开始和结束日期">
</div>
</div>
JavaScript逻辑编写
定义开始日期、结束日期两个变量,监听Datepicker的changeDate事件处理日期选择逻辑,同时自定义beforeShowDay方法实现范围高亮:
$(function() {
// 定义开始日期和结束日期变量
let startDate = null;
let endDate = null;
// 初始化日期选择器
$('#dateRangePicker').datepicker({
format: 'yyyy-mm-dd',
language: 'zh-CN',
autoclose: false, // 不自动关闭,方便选择第二个日期
todayHighlight: true,
beforeShowDay: function(date) {
// 将当前遍历的日期转换为时间戳
const currentTs = date.getTime();
// 如果开始日期和结束日期都存在,判断当前日期是否在范围内
if (startDate && endDate) {
const startTs = startDate.getTime();
const endTs = endDate.getTime();
// 范围内的日期添加高亮样式
if (currentTs >= startTs && currentTs <= endTs) {
return {
classes: 'selected-range'
};
}
}
// 默认返回空样式
return {};
}
}).on('changeDate', function(e) {
const selectedDate = e.date;
// 如果还没有开始日期,将当前选择的日期设为开始日期
if (!startDate) {
startDate = selectedDate;
endDate = null;
// 清空输入框显示,等待选择结束日期
$(this).val('');
return;
}
// 如果已经有开始日期,将当前选择的日期设为结束日期
if (!endDate) {
// 如果选择的日期早于开始日期,交换开始和结束日期
if (selectedDate.getTime() < startDate.getTime()) {
endDate = startDate;
startDate = selectedDate;
} else {
endDate = selectedDate;
}
// 格式化日期显示
const formatDate = (date) => {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
};
// 将日期范围显示到输入框中
$(this).val(`${formatDate(startDate)} 至 ${formatDate(endDate)}`);
// 选择完成后关闭日期选择器
$(this).datepicker('hide');
}
});
// 点击输入框时重置选择状态,方便重新选择
$('#dateRangePicker').on('click', function() {
startDate = null;
endDate = null;
$(this).val('');
$(this).datepicker('show');
});
});
样式优化
为范围内的日期添加自定义高亮样式,让用户更清晰地看到选择的日期范围:
.selected-range {
background-color: #c9e2f5 !important;
color: #333 !important;
}
/* 调整开始和结束日期的样式,更突出显示 */
.datepicker table tr td.selected-range:first-child {
background-color: #337ab7 !important;
color: #fff !important;
border-radius: 4px 0 0 4px;
}
.datepicker table tr td.selected-range:last-child {
background-color: #337ab7 !important;
color: #fff !important;
border-radius: 0 4px 4px 0;
}
功能测试与常见问题
完成代码编写后,可以测试以下功能点:
- 第一次点击日期,输入框不显示内容,等待第二次选择
- 第二次点击日期,自动判断顺序,显示正确的日期范围
- 日期范围内的所有日期都有高亮背景
- 重新点击输入框可以清空之前的选择,重新开始选择
如果出现日期格式错误或者高亮不生效的问题,可以检查以下几点:
- 确认
format配置和日期格式化逻辑一致 - 确认
beforeShowDay方法中的时间戳比较逻辑正确 - 确认自定义样式的优先级足够,没有被插件默认样式覆盖
总结
通过扩展Bootstrap Datepicker的事件和配置,我们可以很方便地实现单日历下的日期范围选择功能,核心就是维护开始和结束两个日期状态,结合日期渲染事件实现范围高亮。这种方式不需要引入额外的日期范围选择插件,减少了项目依赖,也更符合已有的技术栈使用习惯,适合大多数需要日期范围选择的前端场景。
Bootstrap_Datepicker日期范围选择单日历前端日期组件JavaScript修改时间:2026-07-22 22:15:46