我正在计划一个虚拟键盘。它适用于简单输入,但是当我在 setInterval 中重复输入时,它只能在不重新聚焦于输入元素的情况下工作,否则光标位置会跳转。 如果有人发现这个问题(我认为任何时候的顺序都是错误的......)
const keyboard = document.querySelector(".keyboard");
const validInputEls = [HTMLInputElement, HTMLTextAreaElement];
// variables and flags
let lastFocusedInput, isTyping, typingInterval;
// get key/value handle exceptions
//(currently with warnings and early returns)
function handleKeyboard(event) {
const key = event.target.closest(".key");
if (!key) return;
if (!lastFocusedInput) {
console.warn("Please first choose a target for your input!");
return;
}
if (!isTyping) {
// start typing in interval here
isTyping = true;
let char = key.dataset.value;
char = char === "Space" ? "\xa0" : char; // doesn't print " "
if (!char) {
console.warn(`Currently no action associated with ${key.innerText}-key.`);
return;
}
typingInterval = setInterval(() => typeRepeatedly(char), 100);
}
}
function typeRepeatedly(char) {
const cursorPosition = lastFocusedInput.selectionStart;
const text = lastFocusedInput.value;
const newValue =
text.substring(0, cursorPosition) + char + text.substring(cursorPosition);
lastFocusedInput.value = newValue;
const newCursorPosition = cursorPosition + 1;
lastFocusedInput.setSelectionRange(newCursorPosition, newCursorPosition);
//lastFocusedInput.focus();// THIS messes cursorPosition!!!!!
// took me only 4 days to find that out
}
function stopTyping() {
clearInterval(typingInterval);
isTyping = false;
}
// set focused if valid
document.addEventListener("focusin", (event) => {
if (!validInputEls.includes(event.target.constructor)) return;
lastFocusedInput = event.target;
});
keyboard.addEventListener("mousedown", handleKeyboard);
keyboard.addEventListener("mouseup", stopTyping);
keyboard.addEventListener("mouseleave", stopTyping);
一个工作示例在这里:https://codepen.io/BarbWire/pen/rNogpOW
我发现焦点问题: 我需要在句柄中设置 event.preventDefault() ,而不是重置焦点