Как отключить новый ввод даты Chrome HTML5?
последнее обновление (V 20.x) Chrome сломал одну из моих форм с новым встроенным типом ввода даты и времени. Я вызываю jQuery UI datepicker в поле даты, и он работал отлично до обновления. После обновления Chrome переопределяет мой заполнитель и делает виджет jQuery UI непригодным для использования.
любые идеи о том, как я могу предотвратить Chrome от беспорядка с моими полями ввода без изменения их типа?
4 ответов
у вас есть несколько различных вариантов.
вы можете обнаружить, что пользователь использует Chrome, нюхая строку агента пользователя и предотвращая события щелчка.
if (navigator.userAgent.indexOf('Chrome') != -1) {
$('input[type=date]').on('click', function(event) {
event.preventDefault();
});
}
нюхать агента пользователя-плохая идея, но это будет работать.
идеальный подход на мой взгляд, чтобы определить, поддерживает ли браузер родной datepicker, если он использует его, если не использовать jQuery UI.
if (!Modernizr.inputtypes['date']) {
$('input[type=date]').datepicker({
// Consistent format with the HTML5 picker
dateFormat: 'yy-mm-dd'
});
}
пример - http://jsfiddle.net/tj_vantoll/8Wn34/
конечно, поскольку Chrome поддерживает собственный выбор даты, пользователь увидит это вместо пользовательского интерфейса jQuery. Но, по крайней мере, у вас не будет столкновения функций, и пользовательский интерфейс будет использоваться для конечного пользователя.
это заинтриговало меня, поэтому я написал что-то об использовании datepicker jQuery UI вместе с собственным элементом управления - http://tjvantoll.com/2012/06/30/creating-a-native-html5-datepicker-with-a-fallback-to-jquery-ui/.
редактировать
Если вам интересно, я недавно выступил с докладом об использовании виджетов jQuery UI наряду с элементами управления HTML5.
это работает для меня:
;
(function ($) {
$(document).ready(function (event) {
$(document).on('click input', 'input[type="date"], input[type="text"].date-picker', function (e) {
var $this = $(this);
$this.prop('type', 'text').datepicker({
showOtherMonths: true,
selectOtherMonths: true,
showButtonPanel: true,
changeMonth: true,
changeYear: true,
dateFormat: 'yy-mm-dd',
showWeek: true,
firstDay: 1
});
setTimeout(function() {
$this.datepicker('show');
}, 1);
});
});
})(jQuery, jQuery.ui);
Я полностью согласен с TJ.
Если вы выполняете какое-либо редактирование, предварительное заполнение или динамическую настройку значений даты, вам также нужно знать, что с 7/3/13 Chrome соблюдает только стандартный формат даты ISO (гггг-ММ-ДД). Он будет отображать даты для пользователя в локальном формате ("mm/dd/yy" для США), но будет игнорировать любые значения, установленные в HTML, которые не являются стандартным форматом ISO.
чтобы конвертировать при загрузке страницы, вы можете использовать сниффер агента пользователя TJ и сделать это:
if (navigator.userAgent.indexOf('Chrome/2') != -1) {
$('input[type=date]').each(function(){
var d = trim(this.getAttribute('value'));
if (d){
d = new Date(d);
var dStr = d.toISOString().split('T')[0];
this.value = dStr;
}
});
}
Если, например, вы решите отключить собственный datepicker и использовать jQuery, вам также нужно будет установить формат даты в соответствии с полем даты Chrome, или он не будет отображать ввод, который отправляет jQuery datepicker:
$('#myDate').datepicker({dateFormat: 'yy-mm-dd'});
добавьте эти две вещи в первый вариант в ответе TJ, и у вас есть datepicker jQuery, работающий в Chrome без ошибок!
полагаться на родных datepickers идеально лучшее решение. Но когда тебе нужно ... что-то, что поддерживает даты отключения, диапазоны дат, или вы просто хотите, чтобы он выглядел красивее, это сработает.
чтобы удалить стрелки и кнопки вращения:
.unstyled::-webkit-inner-spin-button,
.unstyled::-webkit-calendar-picker-indicator {
display: none;
-webkit-appearance: none;
}
вы все еще можете активировать календарь, нажав Alt+Стрелка Вниз(проверено в windows 10).
чтобы отключить, вам нужно добавить немного JavaScript:
dateInput.addEventListener('keydown', function(event) {
if (event.keyIdentifier == "Down") {
event.preventDefault()
}
}, false);