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

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焦点处理或表单渲染兼容性异常导致的:

  1. 焦点自动触发逻辑:Safari可能在页面加载时自动将焦点赋予第一个可交互表单元素,而bootstrap-datepicker默认会在元素获取焦点时展开面板,即使设置了autocomplete="off"也无法阻止这个行为。
  2. 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 06:15:13