我尝试在 Firefox 中实现 Datetime-local,但不起作用,有人有解决方案吗?或者可以用 js 来说明类似 datetime-local 之类的东西?
这就像 FireFox 中的样子:
我只想找到一个解决方案,用户可以在输入上写入日期时间
我完全放弃了使用 datetime-local 的想法,因为用户在使用 Firefox 和 Safari 时抱怨。我这一周都在尝试使用 JQuery ui Datepicker 并将另一个时间选择器合并到一个中。 我有一个非常适合我的应用程序的解决方案。我使用 Clocklet 库来处理时间部分。唯一的缺点是您无法编辑最终日期时间,您必须使用日期和时间按钮。
操作很简单,选择日期,然后选择时间,然后按 Enter。
这是代码:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>jQuery UI Datepicker - Default functionality</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/css/clocklet.min.css">
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
<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 rel="stylesheet" href="//code.jquery.com/ui/1.13.2/themes/base/jquery-ui.css">
<style>
@charset "utf-8";
.timeCloseHidden{
height: 0;
width: 0;
border: none;
background: none;
margin: 0px;
padding: 0 px;
position: absolute;
top: -100px;
}
.input_icon {
font-size: 20px;
float: right;
margin: 5px;
margin-left: 0px;
}
.inputContainer {
display: flex;
align-items: center;
max-width: 276px;
max-width: 276px;
border: 1px solid #ddd;
margin: 0 auto;
}
.input_datetime {
border: none;
width: 0px;
opacity: 0.0;
}
.input_datetime_mask{
width: 140px;
}
.inputStartDateInstanceContainer{
margin: 0px;
}
.date_label{
margin: 2px;
width: 75px;
text-align: right;
}
.clocklet-options-2 {
font-family: "Frank Ruhl Libre", serif;
font-weight: 500;
}
#inputStartClock{
margin: 0 auto;
margin-right: auto;
margin-left: auto;
display: block;
margin-left: 5px;
margin-right: 5px;
/*width: 62px;*/
border: none;
opacity: 0.0;
width: 0px;
}
#startTimeIcon{
background: url(https://stealth-apsvaw.streamhoster.com/aetv_dashboard_hd/icons/clock_20.png);
height: 20px;
width: 20px;
margin-left: -10px;
}
</style>
</head>
<body>
<button class="timeCloseHidden"></button>
<div id="startDateContainer" class="startDateContainer">
<div class="inputContainer">
<span class="date_label">Start Date: </span>
<!--<input type="datetime-local" id="divStartDatetime" class="input_datetime_mask">-->
<div id="divStartDatetime" class="input_datetime_mask"></div>
<input type="text" id="inputStartDate" class="input_datetime" />
<div class="inputStartDateInstanceContainer">
<input id="inputStartClock" class="clocklet-events"
data-clocklet="class-name: clocklet-options-2; format: hh:mm a; alignment: right; append-to: parent;"
placeholder="hh:mm am">
</div>
<div id="startTimeIcon"></div>
</div>
</div>
<script>
(function () {
$( "#inputStartDate" ).datepicker({
showOn: "button",
buttonImage: "https://stealth-apsvaw.streamhoster.com/aetv_dashboard_hd/icons/calendar_20.png",
buttonImageOnly: true,
dateFormat: "mm/dd/yy",
changeMonth: true,
changeYear: true,
minDate: 0,
onSelect: function(dateText) {
var inputEvent = new Event('input', {
bubbles: true
});
document.getElementById("inputStartDate").dispatchEvent(inputEvent);
}
});
const divStartDatetime = document.querySelector('#divStartDatetime');
const inputStartClock = document.querySelector('#inputStartClock');
if(inputStartClock.value === ''){
inputStartClock.value = getTimeFromDate(new Date());
}
const inputStartDate = document.querySelector('#inputStartDate');
if(inputStartDate.value === ''){
inputStartDate.value = new Date();
}
divStartDatetime.innerHTML = formatDisplayDateTime(inputStartDate, inputStartClock);
var inputElement = document.querySelector('.clocklet-events');
document.getElementById("inputStartDate").addEventListener('input', function (event) {
divStartDatetime.innerHTML = formatDisplayDateTime(inputStartDate, inputStartClock);
inputElement.focus();
});
var startTimeIcon = document.querySelector('#startTimeIcon');
startTimeIcon.addEventListener('click', function (event) {
inputElement.focus();
});
inputElement.addEventListener('clocklet.opening', function (event) {
console.log(event.type, event.target.value, event.detail.options);
});
inputElement.addEventListener('clocklet.opened', function (event) {
console.log(event.type, event.target.value, event.detail.options);
});
inputElement.addEventListener('clocklet.closing', function (event) {
console.log(event.type, event.target.value);
});
inputElement.addEventListener('clocklet.closed', function (event) {
console.log(event.type, event.target.value);
});
inputElement.addEventListener('input', function (event) {
divStartDatetime.innerHTML = formatDisplayDateTime(inputStartDate, inputStartClock);
console.log(event.type, event.target.value, event.target.value);
});
inputElement.addEventListener('keydown', function (event) {
//event.preventDefault();
document.querySelector('.timeCloseHidden').focus();
});
function formatDisplayDateTime(theDate, theTime){
return getDateFromDate(new Date(theDate.value)) + " " + formatAMPM(new Date('01/01/1970 '+theTime.value));
}
function convertDate2DateTimePickerMidnight(dateToConvert){
var yyyy = dateToConvert.getFullYear();
var month = (dateToConvert.getMonth()+1).toString().padStart(2, '0');
var day = dateToConvert.getDate().toString().padStart(2, '0');
return yyyy+'-'+month+'-'+day+'T00:00';
}
function convertDate2DateTimePicker(dateToConvert){
var yyyy = dateToConvert.getFullYear();
var month = (dateToConvert.getMonth()+1).toString().padStart(2, '0');
var day = dateToConvert.getDate().toString().padStart(2, '0');
var hour = dateToConvert.getHours().toString().padStart(2, '0');
var minute = dateToConvert.getMinutes().toString().padStart(2, '0');
return yyyy+'-'+month+'-'+day+'T'+hour+':'+minute;
}
function convertDateEndOfToday2DateTimePicker(dateToConvert){
var yyyy = dateToConvert.getFullYear();
var month = (dateToConvert.getMonth()+1).toString().padStart(2, '0');
var day = dateToConvert.getDate().toString().padStart(2, '0');
return yyyy+'-'+month+'-'+day+'T'+'23'+':'+'59';
}
function getTimeFromDate(dateToConvert){
var hour = dateToConvert.getHours().toString().padStart(2, '0');
var minute = dateToConvert.getMinutes().toString().padStart(2, '0');
return hour+':'+minute;
}
function getDateFromDate(dateToConvert){
var yyyy = dateToConvert.getFullYear();
var month = (dateToConvert.getMonth()+1).toString().padStart(2, '0');
var day = dateToConvert.getDate().toString().padStart(2, '0');
return month+'/'+day+'/'+yyyy;
}
function formatAMPM(date) {
console.log(date);
var hours = date.getHours();
var minutes = date.getMinutes();
var ampm = hours >= 12 ? 'pm' : 'am';
hours = hours % 12;
hours = hours ? hours : 12; // the hour '0' should be '12'
minutes = minutes < 10 ? '0'+minutes : minutes;
return hours + ':' + minutes + ' ' + ampm;
}
})();
</script>
</body>
</html>
(function() {
$("#inputStartDate").datepicker({
showOn: "button",
buttonImage: "https://stealth-apsvaw.streamhoster.com/aetv_dashboard_hd/icons/calendar_20.png",
buttonImageOnly: true,
dateFormat: "mm/dd/yy",
changeMonth: true,
changeYear: true,
minDate: 0,
onSelect: function(dateText) {
var inputEvent = new Event('input', {
bubbles: true
});
document.getElementById("inputStartDate").dispatchEvent(inputEvent);
}
});
const divStartDatetime = document.querySelector('#divStartDatetime');
const inputStartClock = document.querySelector('#inputStartClock');
if (inputStartClock.value === '') {
inputStartClock.value = getTimeFromDate(new Date());
}
const inputStartDate = document.querySelector('#inputStartDate');
if (inputStartDate.value === '') {
inputStartDate.value = new Date();
}
divStartDatetime.innerHTML = formatDisplayDateTime(inputStartDate, inputStartClock);
var inputElement = document.querySelector('.clocklet-events');
document.getElementById("inputStartDate").addEventListener('input', function(event) {
divStartDatetime.innerHTML = formatDisplayDateTime(inputStartDate, inputStartClock);
inputElement.focus();
});
var startTimeIcon = document.querySelector('#startTimeIcon');
startTimeIcon.addEventListener('click', function(event) {
inputElement.focus();
});
inputElement.addEventListener('clocklet.opening', function(event) {
//console.log(event.type, event.target.value, event.detail.options);
});
inputElement.addEventListener('clocklet.opened', function(event) {
//console.log(event.type, event.target.value, event.detail.options);
});
inputElement.addEventListener('clocklet.closing', function(event) {
//console.log(event.type, event.target.value);
});
inputElement.addEventListener('clocklet.closed', function(event) {
//console.log(event.type, event.target.value);
});
inputElement.addEventListener('input', function(event) {
divStartDatetime.innerHTML = formatDisplayDateTime(inputStartDate, inputStartClock);
//console.log(event.type, event.target.value, event.target.value);
});
inputElement.addEventListener('keydown', function(event) {
//event.preventDefault();
document.querySelector('.timeCloseHidden').focus();
});
function formatDisplayDateTime(theDate, theTime) {
return getDateFromDate(new Date(theDate.value)) + " " + formatAMPM(new Date('01/01/1970 ' + theTime.value));
}
function convertDate2DateTimePickerMidnight(dateToConvert) {
var yyyy = dateToConvert.getFullYear();
var month = (dateToConvert.getMonth() + 1).toString().padStart(2, '0');
var day = dateToConvert.getDate().toString().padStart(2, '0');
return yyyy + '-' + month + '-' + day + 'T00:00';
}
function convertDate2DateTimePicker(dateToConvert) {
var yyyy = dateToConvert.getFullYear();
var month = (dateToConvert.getMonth() + 1).toString().padStart(2, '0');
var day = dateToConvert.getDate().toString().padStart(2, '0');
var hour = dateToConvert.getHours().toString().padStart(2, '0');
var minute = dateToConvert.getMinutes().toString().padStart(2, '0');
return yyyy + '-' + month + '-' + day + 'T' + hour + ':' + minute;
}
function convertDateEndOfToday2DateTimePicker(dateToConvert) {
var yyyy = dateToConvert.getFullYear();
var month = (dateToConvert.getMonth() + 1).toString().padStart(2, '0');
var day = dateToConvert.getDate().toString().padStart(2, '0');
return yyyy + '-' + month + '-' + day + 'T' + '23' + ':' + '59';
}
function getTimeFromDate(dateToConvert) {
var hour = dateToConvert.getHours().toString().padStart(2, '0');
var minute = dateToConvert.getMinutes().toString().padStart(2, '0');
return hour + ':' + minute;
}
function getDateFromDate(dateToConvert) {
var yyyy = dateToConvert.getFullYear();
var month = (dateToConvert.getMonth() + 1).toString().padStart(2, '0');
var day = dateToConvert.getDate().toString().padStart(2, '0');
return month + '/' + day + '/' + yyyy;
}
function formatAMPM(date) {
//console.log(date);
var hours = date.getHours();
var minutes = date.getMinutes();
var ampm = hours >= 12 ? 'pm' : 'am';
hours = hours % 12;
hours = hours ? hours : 12; // the hour '0' should be '12'
minutes = minutes < 10 ? '0' + minutes : minutes;
return hours + ':' + minutes + ' ' + ampm;
}
})();
@charset "utf-8";
.timeCloseHidden {
height: 0;
width: 0;
border: none;
background: none;
margin: 0px;
padding: 0 px;
position: absolute;
top: -100px;
}
.input_icon {
font-size: 20px;
float: right;
margin: 5px;
margin-left: 0px;
}
.inputContainer {
display: flex;
align-items: center;
max-width: 276px;
max-width: 276px;
border: 1px solid #ddd;
margin: 0 auto;
}
.input_datetime {
border: none;
width: 0px;
opacity: 0.0;
}
.input_datetime_mask {
width: 140px;
}
.inputStartDateInstanceContainer {
margin: 0px;
}
.date_label {
margin: 2px;
width: 75px;
text-align: right;
}
.clocklet-options-2 {
font-family: "Frank Ruhl Libre", serif;
font-weight: 500;
}
#inputStartClock {
margin: 0 auto;
margin-right: auto;
margin-left: auto;
display: block;
margin-left: 5px;
margin-right: 5px;
/*width: 62px;*/
border: none;
opacity: 0.0;
width: 0px;
}
#startTimeIcon {
background: url(https://stealth-apsvaw.streamhoster.com/aetv_dashboard_hd/icons/clock_20.png);
height: 20px;
width: 20px;
margin-left: -10px;
}
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>jQuery UI Datepicker - Default functionality</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/css/clocklet.min.css">
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
<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 rel="stylesheet" href="//code.jquery.com/ui/1.13.2/themes/base/jquery-ui.css">
</head>
<body>
<button class="timeCloseHidden"></button>
<div id="startDateContainer" class="startDateContainer">
<div class="inputContainer">
<span class="date_label">Start Date: </span>
<!--<input type="datetime-local" id="divStartDatetime" class="input_datetime_mask">-->
<div id="divStartDatetime" class="input_datetime_mask"></div>
<input type="text" id="inputStartDate" class="input_datetime" />
<div class="inputStartDateInstanceContainer">
<input id="inputStartClock" class="clocklet-events" data-clocklet="class-name: clocklet-options-2; format: hh:mm a; alignment: right; append-to: parent;" placeholder="hh:mm am">
</div>
<div id="startTimeIcon"></div>
</div>
</div>
</body>
</html>
哎呀,你是100%正确的。 FireFox 绝对是一团糟,一列大火车在巨大的火球中从铁轨上掉下来。
考虑到这个简单的标记:
<div style="float: left">
<h3>TextMode="Date"</h3>
<asp:TextBox ID="txtMyDate" runat="server"
TextMode="Date">
</asp:TextBox>
</div>
<div style="float:left;margin-left:45px">
<h3>TextMode="Time"</h3>
<asp:TextBox ID="txtMyTime" runat="server"
TextMode="Time">
</asp:TextBox>
</div>
<div style="float:left;margin-left:35px">
<h3>TextMode="DateTimeLocal"</h3>
<asp:TextBox ID="txtMyDTime" runat="server"
TextMode="DateTimeLocal">
</asp:TextBox>
</div>
在 Edge(新 Chrome 版本)和 Google Chrome 中,我们得到/看到:
如您所见,对于日期、时间和日期时间,Edge 和 Google Chrome 浏览器都可以正常工作。
然而,FireFox 崩溃了,无法工作,并失败地产生了一个巨大的火球:
哇!我一直是 Firefox 的忠实粉丝,但这对整个 asp.net 社区来说是一个巨大的破坏。
因此,如上所示,使用 FireFox,数据选择器确实可以工作,但时间选择器不会弹出对话框(它确实显示输入掩码)。日期+时间选择器在巨大的火球中失败了。
所以,我能想到两种解决方案:
一:简单警告并告诉用户不要使用 FireFox,因为它简单地失败、不起作用,并且无法执行简单的基于 Web 的任务,例如选择时间。
二:采用第三方 jQuery 或引导库,允许某种弹出对话框或时间选择器。有很多可供选择,但尝试在带有 FireFox 自动时间选择器的表单上使用输入控件目前根本不是一个选项。
因此,FireFox 根本不起作用,无法使用,或者如上所述,如果您想支持 FireFox,那么您必须引入第 3 方时间选择器,因为基于内置浏览器的时间选择器无法使用。
JavaScript 示例库有无数种选择,但开箱即用的 Firefox 并不是一个有效的选择。您需要采用第 3 方代码才能使其工作。