Yii2中bootstrap-datepicker在Safari v16.5初始化时自动展开问题
Safari 16.5中bootstrap-datepicker首次加载自动展开的问题(Yii2环境)
我在Yii2框架中使用bootstrap-datepicker v1.4.0(搭配jQuery 3.6.0),遇到一个兼容性问题:仅在Safari v16.5浏览器中,页面首次加载时日期选择器会自动展开。同项目中其他DOM结构、脚本逻辑类似的页面均无此现象。
相关代码
PHP(Yii2视图代码)
<?php Pjax::begin([ 'timeout' => false ]); $form = ActiveForm::begin([ 'method' => 'get', 'options' => [ 'class' =>'row mb-3', 'id' => 'form_filter' ] ]); ?> <div class="col-12 col-md-3 offset-md-9 text-center"> <div class="row no-gutters"> <?= $form->field($searchModel, 'date_param', [ 'options' => ['class' => 'input-group input-group-sm'], 'template' => '{input}<div class="input-group-append"> <span class="input-group-text bg-success text-white"> <i class="mdi mdi-calendar"></i> </span> </div>' ])->textInput([ 'id'=>'date_param', 'placeholder' => 'Search by date..', 'autocomplete' => 'off' ])->label(false); ?> </div> </div> <?php ActiveForm::end(); ?> <div class="table-responsive"> <?= GridView::widget([ // GridView包含Select2筛选组件 ]) ?> </div> <?php Pjax::end(); ?>
JS(日期选择器初始化代码)
jQuery('#date_param').datepicker({ format: 'yyyy-mm-dd', autoclose: true, todayHighlight : false });
临时解决方案
目前找到两个可缓解问题的临时办法:
- 在
date_param输入框前添加一个虚拟文本输入框 - 将GridView包含到ActiveForm内部,把
ActiveForm::end()移至Pjax::end()的前一行
问题分析与针对性解决建议
问题根源分析
这个问题是Safari 16.5的DOM焦点处理或表单渲染兼容性异常导致的:
- 焦点自动触发逻辑:Safari可能在页面加载时自动将焦点赋予第一个可交互表单元素,而bootstrap-datepicker默认会在元素获取焦点时展开面板,即使设置了
autocomplete="off"也无法阻止这个行为。 - Pjax与ActiveForm的结构冲突:当前页面中ActiveForm在Pjax内部,但GridView在ActiveForm外部,这种拆分的结构可能导致Safari渲染时出现异常的焦点传递,触发日期选择器意外展开——其他页面结构正常所以无此问题。
具体解决办法
1. 禁止焦点触发日期选择器展开
修改datepicker初始化配置,添加showOnFocus: false参数(bootstrap-datepicker v1.4.0支持该配置):
jQuery('#date_param').datepicker({ format: 'yyyy-mm-dd', autoclose: true, todayHighlight : false, showOnFocus: false // 新增:阻止焦点触发展开 });
如果该参数无效,可在初始化后强制关闭一次:
var dpInstance = jQuery('#date_param').datepicker({ format: 'yyyy-mm-dd', autoclose: true, todayHighlight : false }); // 初始化完成后立即关闭面板 dpInstance.datepicker('hide');
2. 调整焦点优先级
不需要添加虚拟输入框,直接通过tabindex调整页面元素的焦点优先级:
- 给
date_param输入框设置较高的tabindex,避免成为页面首个焦点目标:
// 在textInput配置中添加 'tabindex' => '2'
- 在页面顶部添加一个不可见的焦点占位元素:
<div tabindex="1" style="outline: none; height: 0; width: 0;"></div>
3. 确保Pjax回调中正确初始化日期选择器
由于页面使用了Pjax,需确保初始化代码在Pjax完成后也能执行(Safari对Pjax内元素的渲染可能有延迟):
jQuery(document).on('pjax:complete', function() { jQuery('#date_param').datepicker({ format: 'yyyy-mm-dd', autoclose: true, todayHighlight : false, showOnFocus: false }); });
4. 排查GridView中Select2的干扰
GridView中的Select2组件可能在渲染时触发焦点变化,导致Safari的焦点回流到datepicker输入框。可以尝试给Select2添加初始化延迟,或设置dropdownAutoWidth: false等参数,避免其加载时干扰焦点逻辑。
内容的提问来源于stack exchange,提问作者Prabowo Murti
相关产品推荐
相关产品推荐

