jQuery Datepicker自定义问题:添加Close按钮及autoclose失效排查
jQuery UI Datepicker 定制问题解决方案
问题1:无法在日历底部添加自定义Close按钮
问题原因
beforeShow回调中,$(this)指向输入框元素,而非日历面板容器,因此无法通过thisCalendar.find('.ui-datepicker-buttonpane')定位到按钮面板。beforeShow触发时机早于日历面板的DOM渲染完成,此时按钮面板尚未生成,直接操作会无效。
修复方案
- 通过
$(this).datepicker('widget')获取日历的容器DOM。 - 使用
setTimeout延迟执行添加按钮的代码,确保按钮面板已渲染完成。 - 添加前先移除已存在的Close按钮,避免重复创建。
问题2:选择日期后日历自动关闭,设置autoclose无效
问题原因
jQuery UI Datepicker 原生没有autoclose配置项,该选项属于 Bootstrap Datepicker,因此设置后无效果。手动用CSS控制显示/隐藏会破坏Datepicker内部的状态管理,导致active类失效。
修复方案
- 重写
$.datepicker._selectDate方法,移除默认的关闭日历逻辑,仅保留日期选择后的赋值操作。 - 为默认的Done按钮绑定点击事件,点击时调用
datepicker('hide')方法关闭日历,保证内部状态正常。
修正后的完整代码
<link rel="stylesheet" href="//code.jquery.com/ui/1.13.2/themes/base/jquery-ui.css"> <script src="https://code.jquery.com/jquery-3.6.0.js"></script> <script src="https://code.jquery.com/ui/1.13.2/jquery-ui.js"></script> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous"> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4" crossorigin="anonymous"></script> <script> $(function(){ // 重写_selectDate方法,移除自动关闭日历的默认逻辑 $.datepicker._selectDate = function(id, dateStr) { var target = $(id); var inst = this._getInst(target[0]); dateStr = (dateStr != null ? dateStr : this._formatDate(inst)); if (inst.input) { inst.input.val(dateStr); } this._updateAlternate(inst); var onSelect = this._get(inst, "onSelect"); if (onSelect) { onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); } // 注释默认关闭代码,实现选日期不关闭 // this._hideDatepicker(); }; $(".datepicker").datepicker({ dateFormat: 'yy. mm. dd', changeMonth: true, changeYear: true, showButtonPanel: true, todayBtn: false, monthNames: ["1","2","3","4","5","6","7","8","9","10","11","12"], defaultDate: new Date(), minDate: "+1d", showOtherMonths: false, dayNamesMin: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], firstDay: 0, beforeShow : function(input, inst){ setTimeout(function(){ // 获取日历容器DOM var calendarWidget = $(input).datepicker('widget'); var btnWrap = calendarWidget.find('.ui-datepicker-buttonpane'); // 移除已存在的Close按钮,避免重复添加 btnWrap.find('.ui-datepicker-close-btn').remove(); // 添加样式对齐默认按钮的Close按钮 btnWrap.append('<button class="ui-datepicker-close-btn ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" type="button">Close</button>'); // 绑定Close按钮的关闭事件 btnWrap.find('.ui-datepicker-close-btn').on('click', function(){ $(input).datepicker('hide'); }); }, 10); }, onClose: function(){ // 关闭时移除Close按钮,避免多个日历实例冲突 $('.ui-datepicker-close-btn').remove(); } }) .focus(function() { var thisCalendar = $(this); $('.ui-datepicker-calendar').detach(); var month = $("#ui-datepicker-div .ui-datepicker-month :selected").val(); var year = $("#ui-datepicker-div .ui-datepicker-year :selected").val(); thisCalendar.datepicker('setDate', new Date(year, month, 1)); // 用datepicker原生show方法替代手动设置display thisCalendar.datepicker('show'); }); // 为默认Done按钮绑定关闭事件 $(document).on('click', '.ui-datepicker-buttonpane .ui-datepicker-button', function(){ $('.datepicker').datepicker('hide'); }); $(".datepicker").datepicker("setDate", new Date()); }); </script> <p>Date 1: <input id="datepicker1" class="datepicker" type="text" ></p> <p>Date 2: <input id="datepicker2" class="datepicker" type="text" ></p> <p>Date 3: <input id="datepicker3" class="datepicker" type="text" ></p>
内容的提问来源于stack exchange,提问作者Hailey
相关产品推荐
相关产品推荐

