Rails 5中Bootstrap引发JQuery UI Datepicker响应式失效问题
解决Rails 5中jQuery UI Datepicker在移动端/平板尺寸下无法弹出的问题
我最近开发带搜索栏的Rails 5首页时碰到个头疼的问题:用jQuery UI Datepicker做的日期输入框,在正常浏览器尺寸下点击能正常弹出日历,但把浏览器缩到平板或移动端尺寸时,点击start_date输入框完全没反应,控制台还一点报错都没有,排查起来特别麻烦。
我的相关代码
视图层(ERB代码)
<!-- Tool list --> <div class="searchbar"> <%= form_tag search_path, method: :get do %> <div class="row"> <div class="col-md-6 mobile_searchbar_form"> <%= text_field_tag :search, params[:search], id:"address-input", placeholder: t('whereneedequip'), class: "form-control" %> </div> <div class="col-xs-6 col-md-2 mobile_searchbar_form"> <div class="inner-addon right-addon"> <i class="custom custom-icon-calender"></i> <%= text_field_tag :start_date, params[:start_date], id:"start_date", readonly: true, placeholder: t('startday') , class: "form-control datepicker" %> </div> </div> <div class="col-xs-6 col-md-2 mobile_searchbar_form"> <div class="inner-addon right-addon"> <i class="custom custom-icon-calender"></i> <%= text_field_tag :end_date, params[:end_date], id:"end_date", readonly: true, placeholder: t('endday') , class: "form-control datepicker", disabled: true %> </div> </div> <div class="col-md-2 mobile_searchbar_form "> <%= submit_tag t('search'), class: "btn btn-black-free-account btn-block" %> </div> </div> <% end %> </div>
JavaScript代码(最终移入application.js)
// application.js中的依赖与初始化代码 //= require jquery //= require jquery-ui/widgets/datepicker //= require jquery-ui/widgets/slider //= require rails-ujs //= require jquery.raty //= require holder //= require turbolinks //= require datatables //= require bootstrap-sprockets //= require toastr //= require moment //= require fullcalendar //= require card //= require Chart.bundle //= require chartkick //= require activestorage //= require cable //= require admin //= require_self //= require_tree . //= require_tree ./channels $( document ).on('turbolinks:load', function() { $('#start_date').datepicker({ dateFormat: 'dd-mm-yy', minDate: 0, maxDate: '3m', onSelect: function(selected) { $('#end_date').datepicker("option", "minDate", selected); $('#end_date').attr("disabled", false); } }); $('#end_date').datepicker({ dateFormat: 'dd-mm-yy', minDate: 0, maxDate: '3m', onSelect: function(selected) { $('#start_date').datepicker("option", "maxDate", selected); } }); });
排查过程
一开始我以为是JavaScript的锅:比如Turbolinks加载时机不对,或者Datepicker初始化有问题,于是把内联脚本移到了application.js里,还用turbolinks:load事件包裹了初始化代码,但问题照旧。
控制台没报错,说明JS逻辑本身没问题。后来我试着把日期输入框所在div的col-xs-6 col-md-2类删掉,神奇的是,日历在平板/移动端尺寸下居然正常弹出来了!
问题根源
这其实是Bootstrap栅格布局的冲突问题:用col-xs-6 col-md-2这类栅格类时,移动端尺寸下该div的宽度被限制得很窄,要么是父元素的overflow属性把弹出的日历给挡住了,要么是点击事件被布局元素拦截,导致Datepicker无法正常触发。
解决方案
给你几个可行的解决思路:
- 调整栅格类:把移动端的栅格类换成更宽的,比如把
col-xs-6改成col-xs-12,让日期输入框在移动端占满一行,布局空间足够了,日历自然能正常弹出。 - 修改父元素overflow属性:检查包含日期输入框的div是否有
overflow: hidden这类属性,有的话改成overflow: visible,避免日历被隐藏。 - 自定义Datepicker弹出位置:初始化Datepicker时添加
position选项,强制日历弹在输入框上方或其他不会被遮挡的位置,比如:
$('#start_date').datepicker({ // 其他原有配置 position: { my: "left top", at: "left bottom", collision: "flip" } });
内容的提问来源于stack exchange,提问作者Steven Smith
相关产品推荐
相关产品推荐

