React 应用程序中的事件 "OnkeyDown" 不同步
Event "OnkeyDown" out of sync in the react app
大家好。我是网络开发新手。我只是不明白为什么第二次触发事件“OnKeyDown”。我的任务是在输入字段中更改(增加、减少)部分日期(日、月、年、小时、分钟、秒)。
应用程序功能:
- 当按下按钮组合'ctrl'+'ArrowUp'时,日期的一部分随着其他部分的可变而改变。
例如,如果当前日期是 2021 年 12 月 31 日,而您将第 31 天更改为第 1 天,则日期将更改为 2022 年 1 月 1 日。
- 当按下“ArrowUp”按钮时,只改变这部分,日期的其他部分是不可变的。
功能的第一步工作正常,现在我创建第二步。我的问题是当我想通过按第二次触发的“ArrowUp”事件来增加天数时,这就是不同步的原因。希望我能够正确解释。
代码中有问题的部分:
增加日期天数
if (e.key === "ArrowUp") {
if (
inputEl.current.selectionStart >= 0 &&
inputEl.current.selectionStart <= 2
) {
e.preventDefault();
let nextMilisec = milisec + 86400000;
setSelection({ start: 0, end: 2 });
setMilisec(nextMilisec);
setDate((prevState) => {
return {
...prevState,
day: new Date(nextMilisec).getDate(),
};
});
cur_date.setDate(day);
setValue(date_format_unmut);
}
减少日期天数
if (
inputEl.current.selectionStart >= 0 &&
inputEl.current.selectionStart <= 2
) {
e.preventDefault();
let nextMilisec = milisec - 86400000;
setSelection({ start: 0, end: 2 });
setMilisec(nextMilisec);
setDate((prevState) => {
return {
...prevState,
day: new Date(nextMilisec).getDate(),
};
});
cur_date.setDate(day);
setValue(date_format_unmut);
}
完整代码(抱歉,我知道很多,我需要重构这个烂摊子。)
import React, { useState, useEffect, useRef } from "react";
import styles from "./DataInput.module.css";
const cur_date = new Date();
const def_day = cur_date.getDate();
const def_month = cur_date.getMonth();
const def_year = cur_date.getFullYear();
const def_hour = cur_date.getHours();
const def_minute = cur_date.getMinutes();
const def_seconds = cur_date.getSeconds();
const dayNames = {
0: "Sunday",
1: "Monday",
2: "Tuesday",
3: "Wednesday",
4: "Thursday",
5: "Friday",
6: "Saturday",
};
const monthNames = {
0: "January",
1: "February",
2: "March",
3: "April",
4: "May",
5: "June",
6: "July",
7: "August",
8: "September",
9: "October",
10: "November",
11: "December",
};
const DataInput = () => {
const [milisec, setMilisec] = useState(cur_date.valueOf());
const [date, setDate] = useState({
day: def_day,
month: def_month,
year: def_year,
hour: def_hour,
minute: def_minute,
second: def_seconds,
});
const { day, month, year, hour, minute, second } = date;
const date_format_unmut = `${("0" + day).slice(-2)}/${
monthNames[month]
}/${year} ${("0" + hour).slice(-2)}:${("0" + minute).slice(-2)}:${(
"0" + second
).slice(-2)}`;
const inputEl = useRef();
const [selection, setSelection] = useState();
const date_format = cur_date.toLocaleString().split(".");
const monthIndex = +date_format[1];
date_format[1] = monthNames[monthIndex - 1];
let string_date_format = date_format.join("/").replace(",", "");
const [value, setValue] = useState(string_date_format);
useEffect(() => {
if (!selection) return; // prevent running on start
const { start, end } = selection;
inputEl.current.focus();
inputEl.current.setSelectionRange(start, end);
}, [selection]);
const keyHandler = (e) => {
if (e.key === "ArrowUp") {
if (
inputEl.current.selectionStart >= 0 &&
inputEl.current.selectionStart <= 2
) {
e.preventDefault();
let nextMilisec = milisec + 86400000;
setSelection({ start: 0, end: 2 });
setMilisec(nextMilisec);
setDate((prevState) => {
return {
...prevState,
day: new Date(nextMilisec).getDate(),
};
});
cur_date.setDate(day);
setValue(date_format_unmut);
}
if (
inputEl.current.selectionStart >= 3 &&
inputEl.current.selectionStart <= date_format[1].length + 3
) {
e.preventDefault();
const newMonth = cur_date.getMonth() + 1;
cur_date.setMonth(newMonth);
console.log(cur_date);
setSelection({
start: 3,
end: date_format[1].length + 3,
});
setDate((prevState) => {
return {
...prevState,
month: cur_date.getMonth() - 1,
};
});
setValue(date_format_unmut);
}
}
if (e.ctrlKey && e.key === "ArrowUp") {
if (
inputEl.current.selectionStart >= 0 &&
inputEl.current.selectionStart <= 1
) {
e.preventDefault();
setSelection({ start: 0, end: 2 });
const newDay = cur_date.setDate(cur_date.getDate() + 1);
const increaseDayData = new Date(newDay).toLocaleString().split(".");
const monthIndex = +increaseDayData[1];
increaseDayData[1] = monthNames[monthIndex - 1];
const addDay_date_format = increaseDayData.join("/").replace(",", "");
setValue(addDay_date_format);
}
if (
inputEl.current.selectionStart >= 3 &&
inputEl.current.selectionStart <= date_format[1].length + 3
) {
const newMonth = cur_date.setMonth(cur_date.getMonth() + 1);
const increaseMonthData = new Date(newMonth)
.toLocaleString()
.split(".");
const monthNumber = increaseMonthData[1];
setSelection({ start: 3, end: monthNames[monthNumber - 1].length + 3 });
const monthIndex = +increaseMonthData[1];
increaseMonthData[1] = monthNames[monthIndex - 1];
const addMonth_date_format = increaseMonthData
.join("/")
.replace(",", "");
setValue(addMonth_date_format);
}
if (
inputEl.current.selectionStart >= date_format[1].length + 4 &&
inputEl.current.selectionStart <= date_format[1].length + 8
) {
const newYear = cur_date.setFullYear(cur_date.getFullYear() + 1);
const increaseYearData = new Date(newYear).toLocaleString().split(".");
setSelection({
start: date_format[1].length + 4,
end: date_format[1].length + 8,
});
const monthIndex = +increaseYearData[1];
increaseYearData[1] = monthNames[monthIndex - 1];
const addYear_date_format = increaseYearData.join("/").replace(",", "");
setValue(addYear_date_format);
}
if (
inputEl.current.selectionStart >= date_format[1].length + 9 &&
inputEl.current.selectionStart <= date_format[1].length + 11
) {
const newHour = cur_date.setHours(cur_date.getHours() + 1);
const increaseHourData = new Date(newHour).toLocaleString().split(".");
setSelection({
start: date_format[1].length + 9,
end: date_format[1].length + 11,
});
const monthIndex = +increaseHourData[1];
increaseHourData[1] = monthNames[monthIndex - 1];
const addHour_date_format = increaseHourData.join("/").replace(",", "");
setValue(addHour_date_format);
}
if (
inputEl.current.selectionStart >= date_format[1].length + 12 &&
inputEl.current.selectionStart <= date_format[1].length + 14
) {
const newMinutes = cur_date.setMinutes(cur_date.getMinutes() + 1);
const increaseMinutesData = new Date(newMinutes)
.toLocaleString()
.split(".");
setSelection({
start: date_format[1].length + 12,
end: date_format[1].length + 14,
});
const monthIndex = +increaseMinutesData[1];
increaseMinutesData[1] = monthNames[monthIndex - 1];
const addMinutes_date_format = increaseMinutesData
.join("/")
.replace(",", "");
setValue(addMinutes_date_format);
}
if (
inputEl.current.selectionStart >= date_format[1].length + 15 &&
inputEl.current.selectionStart <= date_format[1].length + 17
) {
const newSeconds = cur_date.setSeconds(cur_date.getSeconds() + 1);
const increaseSecondsData = new Date(newSeconds)
.toLocaleString()
.split(".");
setSelection({
start: date_format[1].length + 15,
end: date_format[1].length + 17,
});
const monthIndex = +increaseSecondsData[1];
increaseSecondsData[1] = monthNames[monthIndex - 1];
const addSeconds_date_format = increaseSecondsData
.join("/")
.replace(",", "");
setValue(addSeconds_date_format);
}
}
if (e.key === "ArrowDown") {
if (
inputEl.current.selectionStart >= 0 &&
inputEl.current.selectionStart <= 2
) {
e.preventDefault();
let nextMilisec = milisec - 86400000;
setSelection({ start: 0, end: 2 });
setMilisec(nextMilisec);
setDate((prevState) => {
return {
...prevState,
day: new Date(nextMilisec).getDate(),
};
});
cur_date.setDate(day);
setValue(date_format_unmut);
}
}
if (e.ctrlKey && e.key === "ArrowDown") {
e.preventDefault();
if (
inputEl.current.selectionStart >= 0 &&
inputEl.current.selectionStart <= 1
) {
setSelection({ start: 0, end: 2 });
const newDay = cur_date.setDate(cur_date.getDate() - 1);
const increaseDayData = new Date(newDay).toLocaleString().split(".");
const monthIndex = +increaseDayData[1];
increaseDayData[1] = monthNames[monthIndex - 1];
const addDay_date_format = increaseDayData.join("/").replace(",", "");
setValue(addDay_date_format);
}
if (
inputEl.current.selectionStart >= 3 &&
inputEl.current.selectionStart <= date_format[1].length + 3
) {
const newMonth = cur_date.setMonth(cur_date.getMonth() - 1);
const increaseMonthData = new Date(newMonth)
.toLocaleString()
.split(".");
const monthNumber = increaseMonthData[1];
setSelection({ start: 3, end: monthNames[monthNumber - 1].length + 3 });
const monthIndex = +increaseMonthData[1];
increaseMonthData[1] = monthNames[monthIndex - 1];
const addMonth_date_format = increaseMonthData
.join("/")
.replace(",", "");
setValue(addMonth_date_format);
}
if (
inputEl.current.selectionStart >= date_format[1].length + 4 &&
inputEl.current.selectionStart <= date_format[1].length + 8
) {
const newYear = cur_date.setFullYear(cur_date.getFullYear() - 1);
const increaseYearData = new Date(newYear).toLocaleString().split(".");
setSelection({
start: date_format[1].length + 4,
end: date_format[1].length + 8,
});
const monthIndex = +increaseYearData[1];
increaseYearData[1] = monthNames[monthIndex - 1];
const addYear_date_format = increaseYearData.join("/").replace(",", "");
setValue(addYear_date_format);
}
if (
inputEl.current.selectionStart >= date_format[1].length + 9 &&
inputEl.current.selectionStart <= date_format[1].length + 11
) {
const newHour = cur_date.setHours(cur_date.getHours() - 1);
const increaseHourData = new Date(newHour).toLocaleString().split(".");
setSelection({
start: date_format[1].length + 9,
end: date_format[1].length + 11,
});
const monthIndex = +increaseHourData[1];
increaseHourData[1] = monthNames[monthIndex - 1];
const addHour_date_format = increaseHourData.join("/").replace(",", "");
setValue(addHour_date_format);
}
if (
inputEl.current.selectionStart >= date_format[1].length + 12 &&
inputEl.current.selectionStart <= date_format[1].length + 14
) {
const newMinutes = cur_date.setMinutes(cur_date.getMinutes() - 1);
const increaseMinutesData = new Date(newMinutes)
.toLocaleString()
.split(".");
setSelection({
start: date_format[1].length + 12,
end: date_format[1].length + 14,
});
const monthIndex = +increaseMinutesData[1];
increaseMinutesData[1] = monthNames[monthIndex - 1];
const addMinutes_date_format = increaseMinutesData
.join("/")
.replace(",", "");
setValue(addMinutes_date_format);
}
if (
inputEl.current.selectionStart >= date_format[1].length + 15 &&
inputEl.current.selectionStart <= date_format[1].length + 17
) {
const newSeconds = cur_date.setSeconds(cur_date.getSeconds() - 1);
const increaseSecondsData = new Date(newSeconds)
.toLocaleString()
.split(".");
setSelection({
start: date_format[1].length + 15,
end: date_format[1].length + 17,
});
const monthIndex = +increaseSecondsData[1];
increaseSecondsData[1] = monthNames[monthIndex - 1];
const addSeconds_date_format = increaseSecondsData
.join("/")
.replace(",", "");
setValue(addSeconds_date_format);
}
}
};
const fullDateScreen = cur_date.toLocaleString().split(" ");
const timeScreen = fullDateScreen[1];
const dateScreen = fullDateScreen[0];
const dayScreen = dayNames[cur_date.getDay()];
const monthScreen = monthNames[cur_date.getMonth()];
const dateScreenFormat = dateScreen.replaceAll(".", " ");
const firstNumber = dateScreenFormat[0];
const smallDateFormat =
dayScreen + "," + " " + dateScreenFormat.slice(1, -8) + " " + monthScreen;
const bigDateFormat =
dayScreen + "," + " " + dateScreenFormat.slice(0, -8) + " " + monthScreen;
const changeHandler = (e) => {
setValue(e.target.value);
};
return (
<div className={styles.content}>
<div className={styles.inputDublicat}>
<h1>{timeScreen.slice(0, 5)}</h1>
<p>{firstNumber == 0 ? smallDateFormat : bigDateFormat}</p>
</div>
<div className={styles.bodyFlex}>
<div className={styles.main}>
<div>
<h1 className={styles.title}> Frontend Task</h1>
<input
ref={inputEl}
value={value}
onChange={changeHandler}
onKeyDown={keyHandler}
/>
<div className={styles.textBlock}>
<div className={styles.instruction}>
<p>
You can change input parts of date
(day,month,year,hour,minutes,seconds) by pressing buttons or
combination. The cursor must be on the focus in the input
field.
</p>
</div>
<div>
<h3>Buttons </h3>
<p>↑ - unmutable date</p>
<p>↓ - unmutable date</p>
</div>
<div>
<h3>Combinations</h3>
<p>"CTRL" + ↑ - mutable date</p>
<p>"CTRL" + ↓ - unmutable date</p>
</div>
</div>
</div>
</div>
<div>
<p className={styles.name}>DAVID ABRAMOV</p>
<hr width="450%" className={styles.line} />
</div>
</div>
</div>
);
};
export default DataInput;
我猜您收到了两个 keyDown 事件,因为“ctrl”和“向上箭头”键都会触发它们自己单独的 keyDown 事件。
检查这一点的最简单方法是观察 e.key == "arrowUp"
,然后检查事件的修饰符状态以查看是否也按下了“Control”。
(您还应确认该组合键未被其他功能阻止;在我的笔记本电脑上按 ctrl-arrow-up 启动 OSX 的 Mission Control 应用程序,老实说,我不记得是否这是默认组合键或我设置但忘记的东西)
(注意键名是not standardized,其他情况下需要构建跨平台跨浏览器支持。)
document.getElementById("foo").addEventListener("keydown", e => {
console.log("Event key: ", e.key)
console.log("Control modifier:", e.getModifierState("Control"))
if (e.key === "ArrowUp" && e.getModifierState("Control")) {
console.log("Ctrl-arrow-up pressed");
}
})
Type in here: <input id="foo">
大家好。我是网络开发新手。我只是不明白为什么第二次触发事件“OnKeyDown”。我的任务是在输入字段中更改(增加、减少)部分日期(日、月、年、小时、分钟、秒)。
应用程序功能:
- 当按下按钮组合'ctrl'+'ArrowUp'时,日期的一部分随着其他部分的可变而改变。 例如,如果当前日期是 2021 年 12 月 31 日,而您将第 31 天更改为第 1 天,则日期将更改为 2022 年 1 月 1 日。
- 当按下“ArrowUp”按钮时,只改变这部分,日期的其他部分是不可变的。
功能的第一步工作正常,现在我创建第二步。我的问题是当我想通过按第二次触发的“ArrowUp”事件来增加天数时,这就是不同步的原因。希望我能够正确解释。
代码中有问题的部分:
增加日期天数
if (e.key === "ArrowUp") {
if (
inputEl.current.selectionStart >= 0 &&
inputEl.current.selectionStart <= 2
) {
e.preventDefault();
let nextMilisec = milisec + 86400000;
setSelection({ start: 0, end: 2 });
setMilisec(nextMilisec);
setDate((prevState) => {
return {
...prevState,
day: new Date(nextMilisec).getDate(),
};
});
cur_date.setDate(day);
setValue(date_format_unmut);
}
减少日期天数
if (
inputEl.current.selectionStart >= 0 &&
inputEl.current.selectionStart <= 2
) {
e.preventDefault();
let nextMilisec = milisec - 86400000;
setSelection({ start: 0, end: 2 });
setMilisec(nextMilisec);
setDate((prevState) => {
return {
...prevState,
day: new Date(nextMilisec).getDate(),
};
});
cur_date.setDate(day);
setValue(date_format_unmut);
}
完整代码(抱歉,我知道很多,我需要重构这个烂摊子。)
import React, { useState, useEffect, useRef } from "react";
import styles from "./DataInput.module.css";
const cur_date = new Date();
const def_day = cur_date.getDate();
const def_month = cur_date.getMonth();
const def_year = cur_date.getFullYear();
const def_hour = cur_date.getHours();
const def_minute = cur_date.getMinutes();
const def_seconds = cur_date.getSeconds();
const dayNames = {
0: "Sunday",
1: "Monday",
2: "Tuesday",
3: "Wednesday",
4: "Thursday",
5: "Friday",
6: "Saturday",
};
const monthNames = {
0: "January",
1: "February",
2: "March",
3: "April",
4: "May",
5: "June",
6: "July",
7: "August",
8: "September",
9: "October",
10: "November",
11: "December",
};
const DataInput = () => {
const [milisec, setMilisec] = useState(cur_date.valueOf());
const [date, setDate] = useState({
day: def_day,
month: def_month,
year: def_year,
hour: def_hour,
minute: def_minute,
second: def_seconds,
});
const { day, month, year, hour, minute, second } = date;
const date_format_unmut = `${("0" + day).slice(-2)}/${
monthNames[month]
}/${year} ${("0" + hour).slice(-2)}:${("0" + minute).slice(-2)}:${(
"0" + second
).slice(-2)}`;
const inputEl = useRef();
const [selection, setSelection] = useState();
const date_format = cur_date.toLocaleString().split(".");
const monthIndex = +date_format[1];
date_format[1] = monthNames[monthIndex - 1];
let string_date_format = date_format.join("/").replace(",", "");
const [value, setValue] = useState(string_date_format);
useEffect(() => {
if (!selection) return; // prevent running on start
const { start, end } = selection;
inputEl.current.focus();
inputEl.current.setSelectionRange(start, end);
}, [selection]);
const keyHandler = (e) => {
if (e.key === "ArrowUp") {
if (
inputEl.current.selectionStart >= 0 &&
inputEl.current.selectionStart <= 2
) {
e.preventDefault();
let nextMilisec = milisec + 86400000;
setSelection({ start: 0, end: 2 });
setMilisec(nextMilisec);
setDate((prevState) => {
return {
...prevState,
day: new Date(nextMilisec).getDate(),
};
});
cur_date.setDate(day);
setValue(date_format_unmut);
}
if (
inputEl.current.selectionStart >= 3 &&
inputEl.current.selectionStart <= date_format[1].length + 3
) {
e.preventDefault();
const newMonth = cur_date.getMonth() + 1;
cur_date.setMonth(newMonth);
console.log(cur_date);
setSelection({
start: 3,
end: date_format[1].length + 3,
});
setDate((prevState) => {
return {
...prevState,
month: cur_date.getMonth() - 1,
};
});
setValue(date_format_unmut);
}
}
if (e.ctrlKey && e.key === "ArrowUp") {
if (
inputEl.current.selectionStart >= 0 &&
inputEl.current.selectionStart <= 1
) {
e.preventDefault();
setSelection({ start: 0, end: 2 });
const newDay = cur_date.setDate(cur_date.getDate() + 1);
const increaseDayData = new Date(newDay).toLocaleString().split(".");
const monthIndex = +increaseDayData[1];
increaseDayData[1] = monthNames[monthIndex - 1];
const addDay_date_format = increaseDayData.join("/").replace(",", "");
setValue(addDay_date_format);
}
if (
inputEl.current.selectionStart >= 3 &&
inputEl.current.selectionStart <= date_format[1].length + 3
) {
const newMonth = cur_date.setMonth(cur_date.getMonth() + 1);
const increaseMonthData = new Date(newMonth)
.toLocaleString()
.split(".");
const monthNumber = increaseMonthData[1];
setSelection({ start: 3, end: monthNames[monthNumber - 1].length + 3 });
const monthIndex = +increaseMonthData[1];
increaseMonthData[1] = monthNames[monthIndex - 1];
const addMonth_date_format = increaseMonthData
.join("/")
.replace(",", "");
setValue(addMonth_date_format);
}
if (
inputEl.current.selectionStart >= date_format[1].length + 4 &&
inputEl.current.selectionStart <= date_format[1].length + 8
) {
const newYear = cur_date.setFullYear(cur_date.getFullYear() + 1);
const increaseYearData = new Date(newYear).toLocaleString().split(".");
setSelection({
start: date_format[1].length + 4,
end: date_format[1].length + 8,
});
const monthIndex = +increaseYearData[1];
increaseYearData[1] = monthNames[monthIndex - 1];
const addYear_date_format = increaseYearData.join("/").replace(",", "");
setValue(addYear_date_format);
}
if (
inputEl.current.selectionStart >= date_format[1].length + 9 &&
inputEl.current.selectionStart <= date_format[1].length + 11
) {
const newHour = cur_date.setHours(cur_date.getHours() + 1);
const increaseHourData = new Date(newHour).toLocaleString().split(".");
setSelection({
start: date_format[1].length + 9,
end: date_format[1].length + 11,
});
const monthIndex = +increaseHourData[1];
increaseHourData[1] = monthNames[monthIndex - 1];
const addHour_date_format = increaseHourData.join("/").replace(",", "");
setValue(addHour_date_format);
}
if (
inputEl.current.selectionStart >= date_format[1].length + 12 &&
inputEl.current.selectionStart <= date_format[1].length + 14
) {
const newMinutes = cur_date.setMinutes(cur_date.getMinutes() + 1);
const increaseMinutesData = new Date(newMinutes)
.toLocaleString()
.split(".");
setSelection({
start: date_format[1].length + 12,
end: date_format[1].length + 14,
});
const monthIndex = +increaseMinutesData[1];
increaseMinutesData[1] = monthNames[monthIndex - 1];
const addMinutes_date_format = increaseMinutesData
.join("/")
.replace(",", "");
setValue(addMinutes_date_format);
}
if (
inputEl.current.selectionStart >= date_format[1].length + 15 &&
inputEl.current.selectionStart <= date_format[1].length + 17
) {
const newSeconds = cur_date.setSeconds(cur_date.getSeconds() + 1);
const increaseSecondsData = new Date(newSeconds)
.toLocaleString()
.split(".");
setSelection({
start: date_format[1].length + 15,
end: date_format[1].length + 17,
});
const monthIndex = +increaseSecondsData[1];
increaseSecondsData[1] = monthNames[monthIndex - 1];
const addSeconds_date_format = increaseSecondsData
.join("/")
.replace(",", "");
setValue(addSeconds_date_format);
}
}
if (e.key === "ArrowDown") {
if (
inputEl.current.selectionStart >= 0 &&
inputEl.current.selectionStart <= 2
) {
e.preventDefault();
let nextMilisec = milisec - 86400000;
setSelection({ start: 0, end: 2 });
setMilisec(nextMilisec);
setDate((prevState) => {
return {
...prevState,
day: new Date(nextMilisec).getDate(),
};
});
cur_date.setDate(day);
setValue(date_format_unmut);
}
}
if (e.ctrlKey && e.key === "ArrowDown") {
e.preventDefault();
if (
inputEl.current.selectionStart >= 0 &&
inputEl.current.selectionStart <= 1
) {
setSelection({ start: 0, end: 2 });
const newDay = cur_date.setDate(cur_date.getDate() - 1);
const increaseDayData = new Date(newDay).toLocaleString().split(".");
const monthIndex = +increaseDayData[1];
increaseDayData[1] = monthNames[monthIndex - 1];
const addDay_date_format = increaseDayData.join("/").replace(",", "");
setValue(addDay_date_format);
}
if (
inputEl.current.selectionStart >= 3 &&
inputEl.current.selectionStart <= date_format[1].length + 3
) {
const newMonth = cur_date.setMonth(cur_date.getMonth() - 1);
const increaseMonthData = new Date(newMonth)
.toLocaleString()
.split(".");
const monthNumber = increaseMonthData[1];
setSelection({ start: 3, end: monthNames[monthNumber - 1].length + 3 });
const monthIndex = +increaseMonthData[1];
increaseMonthData[1] = monthNames[monthIndex - 1];
const addMonth_date_format = increaseMonthData
.join("/")
.replace(",", "");
setValue(addMonth_date_format);
}
if (
inputEl.current.selectionStart >= date_format[1].length + 4 &&
inputEl.current.selectionStart <= date_format[1].length + 8
) {
const newYear = cur_date.setFullYear(cur_date.getFullYear() - 1);
const increaseYearData = new Date(newYear).toLocaleString().split(".");
setSelection({
start: date_format[1].length + 4,
end: date_format[1].length + 8,
});
const monthIndex = +increaseYearData[1];
increaseYearData[1] = monthNames[monthIndex - 1];
const addYear_date_format = increaseYearData.join("/").replace(",", "");
setValue(addYear_date_format);
}
if (
inputEl.current.selectionStart >= date_format[1].length + 9 &&
inputEl.current.selectionStart <= date_format[1].length + 11
) {
const newHour = cur_date.setHours(cur_date.getHours() - 1);
const increaseHourData = new Date(newHour).toLocaleString().split(".");
setSelection({
start: date_format[1].length + 9,
end: date_format[1].length + 11,
});
const monthIndex = +increaseHourData[1];
increaseHourData[1] = monthNames[monthIndex - 1];
const addHour_date_format = increaseHourData.join("/").replace(",", "");
setValue(addHour_date_format);
}
if (
inputEl.current.selectionStart >= date_format[1].length + 12 &&
inputEl.current.selectionStart <= date_format[1].length + 14
) {
const newMinutes = cur_date.setMinutes(cur_date.getMinutes() - 1);
const increaseMinutesData = new Date(newMinutes)
.toLocaleString()
.split(".");
setSelection({
start: date_format[1].length + 12,
end: date_format[1].length + 14,
});
const monthIndex = +increaseMinutesData[1];
increaseMinutesData[1] = monthNames[monthIndex - 1];
const addMinutes_date_format = increaseMinutesData
.join("/")
.replace(",", "");
setValue(addMinutes_date_format);
}
if (
inputEl.current.selectionStart >= date_format[1].length + 15 &&
inputEl.current.selectionStart <= date_format[1].length + 17
) {
const newSeconds = cur_date.setSeconds(cur_date.getSeconds() - 1);
const increaseSecondsData = new Date(newSeconds)
.toLocaleString()
.split(".");
setSelection({
start: date_format[1].length + 15,
end: date_format[1].length + 17,
});
const monthIndex = +increaseSecondsData[1];
increaseSecondsData[1] = monthNames[monthIndex - 1];
const addSeconds_date_format = increaseSecondsData
.join("/")
.replace(",", "");
setValue(addSeconds_date_format);
}
}
};
const fullDateScreen = cur_date.toLocaleString().split(" ");
const timeScreen = fullDateScreen[1];
const dateScreen = fullDateScreen[0];
const dayScreen = dayNames[cur_date.getDay()];
const monthScreen = monthNames[cur_date.getMonth()];
const dateScreenFormat = dateScreen.replaceAll(".", " ");
const firstNumber = dateScreenFormat[0];
const smallDateFormat =
dayScreen + "," + " " + dateScreenFormat.slice(1, -8) + " " + monthScreen;
const bigDateFormat =
dayScreen + "," + " " + dateScreenFormat.slice(0, -8) + " " + monthScreen;
const changeHandler = (e) => {
setValue(e.target.value);
};
return (
<div className={styles.content}>
<div className={styles.inputDublicat}>
<h1>{timeScreen.slice(0, 5)}</h1>
<p>{firstNumber == 0 ? smallDateFormat : bigDateFormat}</p>
</div>
<div className={styles.bodyFlex}>
<div className={styles.main}>
<div>
<h1 className={styles.title}> Frontend Task</h1>
<input
ref={inputEl}
value={value}
onChange={changeHandler}
onKeyDown={keyHandler}
/>
<div className={styles.textBlock}>
<div className={styles.instruction}>
<p>
You can change input parts of date
(day,month,year,hour,minutes,seconds) by pressing buttons or
combination. The cursor must be on the focus in the input
field.
</p>
</div>
<div>
<h3>Buttons </h3>
<p>↑ - unmutable date</p>
<p>↓ - unmutable date</p>
</div>
<div>
<h3>Combinations</h3>
<p>"CTRL" + ↑ - mutable date</p>
<p>"CTRL" + ↓ - unmutable date</p>
</div>
</div>
</div>
</div>
<div>
<p className={styles.name}>DAVID ABRAMOV</p>
<hr width="450%" className={styles.line} />
</div>
</div>
</div>
);
};
export default DataInput;
我猜您收到了两个 keyDown 事件,因为“ctrl”和“向上箭头”键都会触发它们自己单独的 keyDown 事件。
检查这一点的最简单方法是观察 e.key == "arrowUp"
,然后检查事件的修饰符状态以查看是否也按下了“Control”。
(您还应确认该组合键未被其他功能阻止;在我的笔记本电脑上按 ctrl-arrow-up 启动 OSX 的 Mission Control 应用程序,老实说,我不记得是否这是默认组合键或我设置但忘记的东西)
(注意键名是not standardized,其他情况下需要构建跨平台跨浏览器支持。)
document.getElementById("foo").addEventListener("keydown", e => {
console.log("Event key: ", e.key)
console.log("Control modifier:", e.getModifierState("Control"))
if (e.key === "ArrowUp" && e.getModifierState("Control")) {
console.log("Ctrl-arrow-up pressed");
}
})
Type in here: <input id="foo">