I'm trying to emulate the behavior of apps like Discord, where you can type into the message box even if it isn't focused. I'd like to do this only if no other input on the page is focused.
I tried immediately focusing the MessageBox input on blur, but this traps focus in MessageBox doesn't let me type into any other input on the page.
function MessageBox() {
const inputRef = useRef(null);
return <input ref={inputRef} onBlur={() => inputRef.current?.focus()} />;
}
CodePudding user response:
First, you need to add an keydown
event listener to the window
and inside check if the document.activeElement
( which is the focused
element ) tag name not an input
, if yes, then focus the textarea
const textarea = document.querySelector('#textarea');
window.addEventListener('keydown', () => {
const focusedElement = document.activeElement
if (focusedElement.tagName.toLowerCase() !== 'input') {
textarea.focus()
}
})
input {
margin-bottom: 20px;
display: block;
}
<input type="text" />
<textarea id="textarea"></textarea>
CodePudding user response:
You need to listen to the key event from the window.
const MessageBox = () => {
const [value, setValue] = useState('')
useEffect(() => {
const onKeyDown = e => {
if (e.key === 'Enter') {
return
}
if (e.key === 'Backspace') {
return
}
// consloe.log(e) to see other options
setValue(v => v e.code)
}
window.addEventListener('keydown', onKeyDown)
return () => {
window.removeEventListener('keydown', onKeyDown)
}
}, [])
const onChange = e => { setValue(e.target.value) }
return <input value={value} onChange={onChange} />
}
So basically you have two ways to change the value
, one from old onChange
and one from the key event from now on.
CodePudding user response:
Building on @Mina's answer, here's what I ended up doing with React:
function MessageBox() {
const inputRef = useRef(null);
useEffect(() => {
function handler() {
const focusedElement = document.activeElement;
if (
focusedElement?.tagName.toLowerCase() === "input" &&
focusedElement?.id !== "messagebox"
) {
// do nothing
} else {
inputRef.current?.focus();
}
}
window.addEventListener("keydown", handler);
return () => window.removeEventListener("keydown", handler);
}, []);
return <input ref={inputRef} id="messagebox" />;
}