每当有人选择休息日的日期(例如星期六或星期日,它可能是一系列关闭日中的任何一天)时,我想呈现错误。
我有 HTML:
<div>
<input type="date" id="date-input">
</div>
<br>
<div id="error-container">
</div>
CSS:
.d-error{
background: orangered;
color: white;
padding: 4px 8px;
}
这是 JavaScript:
'use strict';
const dateInput = document.getElementById('date-input');
const errorContainer = document.getElementById('error-container');
const closingDays = [0, 6];
const weekDays = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday','Friday', 'Saturday'];
const displayError = function ({ parentEl, message, position = 'prepend', durationSec = 0 }) {
const errorElement = document.createElement('p');
errorElement.classList.add('d-error');
errorElement.textContent = message;
parentEl[position](errorElement);
if (durationSec) {
setTimeout(() => {
errorElement.remove();
}, durationSec * 1000);
}
};
const handleDateChange = function (event) {
const selectedDay = new Date(event.currentTarget.value).getDay();
if (closingDays.includes(selectedDay)) {
displayError({
parentEl: errorContainer,
message: `We are closed on ${weekDays[selectedDay]}. Please select another day.`,
durationSec: 5
});
event.currentTarget.value = '';
}
};
dateInput.addEventListener('change', handleDateChange);
这可行,但错误会呈现两次。一次是由于用户更改,一次是由于以编程方式更改输入值
event.currentTarget.value = '';
。那么,如何暂时删除 change
事件监听器并重新附加到它呢?或者有其他方法可以解决这个问题吗?
我尝试过:
const handleDateChange = function(event) {
...
event.currentTarget.removeEventListener('change', handleDateChange);
event.currentTarget.value = '';
event.currentTarget.addEventListener('change', handleDateChange);
...
}
但这并没有解决问题。
首先,正如@Sebastian 所指出的,以编程方式设置输入的值不会触发
change
事件。所以一定还有其他原因导致事件触发两次。
我非常抱歉没有在 Firefox 以外的其他浏览器中进行测试。这个问题似乎只出现在 Firefox 中,因为在基于 chromium 的浏览器中,一切都按预期工作(尽管在 Firefox android 中工作)。所以,我猜测这是 Firefox 中的某种错误,但我个人无法确认。请尝试在不同的浏览器中运行代码片段。
'use strict';
const dateInput = document.getElementById('date-input');
const errorContainer = document.getElementById('error-container');
const closingDays = [0, 6];
const weekDays = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
const displayError = function({
parentEl,
message,
position = 'prepend',
durationSec = 0
}) {
const errorElement = document.createElement('p');
errorElement.classList.add('d-error');
errorElement.textContent = message;
parentEl[position](errorElement);
if (durationSec) {
setTimeout(() => {
errorElement.remove();
}, durationSec * 1000);
}
};
const handleDateChange = function(event) {
const selectedDay = new Date(event.currentTarget.value).getDay();
if (closingDays.includes(selectedDay)) {
displayError({
parentEl: errorContainer,
message: `We are closed on ${weekDays[selectedDay]}. Please select another day.`,
durationSec: 5
});
event.currentTarget.value = '';
}
};
dateInput.addEventListener('change', handleDateChange);
.d-error {
background: orangered;
color: white;
padding: 4px 8px;
}
<div>
<input type="date" id="date-input">
</div>
<br>
<div id="error-container">
</div>
这里是一个较短版本的代码片段,用于在 Firefox (121) 中重现该错误。 OP 是正确的,第二个事件实际上是由以编程方式设置输入字段的值引起的(情况不应该如此)。但是,第二个事件中打印到控制台的值与第一个事件的值相同。此外,在事件处理程序之外设置值根本不会触发事件(应该如此)。因此,应该将此行为报告给 https://bugzilla.mozilla.org/ .
function onChange(event) {
console.log('changed to ' + dateInput.value)
dateInput.value = ''; // somehow triggers a second event
};
dateInput.addEventListener('change', onChange);
dateInput.value = '2024-02-07'; // does not trigger the event!
<div>
<input type="date" id="dateInput">
</div>