主动调用
input.focus()
可以替用户主动锁定输入框并弹出输入法,引导用户填写表单。
但是在实际的使用中,页面有时并不会按照我们的预想去执行。本文将列举几个限制条件,并给出解决方案。
针对于下列问题场景,我写了一个简易的DEMO供大家亲自试验:
focus-invalid-demo
IOS Safari浏览器下必须由用户点击触发
在IOS Safari浏览器下要求
input.focus()
的调用必须位于
onclick
的回调函数中,且同步执行,例如:
btnElement.
addEventListener
(
'click'
,
function
(
) {
input.
focus
()
反面教材一
在其他位置调用是无效的,例如:
window
.
addEventListener
(
'load'
,
function
(
) {
input.
focus
()
如果你确实要实现这样的功能,可以尝试使用
autofocus
属性
// 页面加载完后立即focus:【有效】
Username:
<
input
type
=
"text"
autofocus
placeholder
=
"来都来了就留下大名吧"
autofocus
可以在页面加载完成后自动focus相应的表单组件,但限制是一个页面只能有一个元素设置该属性。
反面教材二
在点击回调函数中异步调用是无效的,例如:
btnElement.
addEventListener
(
'click'
,
function
(
) {
setTimeout
(
() =>
input.
focus
(),
200
)
常见的异步调用有
setTimeout
、
Promise
。IOS Safari浏览器下,包裹其中的
input.focus()
都是无效的。
目标
<input>
元素必须可见
这里说的可见是指当
input.focus()
调用时要满足以下条件:
目标
<input>
元素已渲染到dom上
目标
<input>
元素不是
display: none;
目标
<input>
元素不是
visibility: hidden;
这种问题常见于调起一个弹框界面,其中
元素恰好位于弹框内,而我们在元素还未可见就调用了
input.focus()
。尤其是在React或者Vue等现代框架中,我们通过设置状态控制弹框的显隐,这种改变反应到dom上并不是同步的,例如:
const
LoginModal
:
React
.
FC
<{}> =
() =>
{
const
[show, setShow] =
useState
(
false
)
const
ref = useRef<
HTMLInputElement
>(
null
)
const
handleClick
= (
) => {
setShow
(
true
)
ref.
current
?.
focus
()
return
(
<
div
className
=
"login-modal-comp"
>
<
button
onClick
=
{handleClick}
>
Show Modal
</
button
>
<
Modal
centered
visible
=
{show}
>
Username:
<
input
ref
=
{ref}
type
=
"text"
placeholder
=
"来都来了就留下大名吧"
/>
</
Modal
>
</
div
>
如果这个恰好是你想要实现的功能,你同样可以借助
autofocus
:
<Modal centered visible={show}>
Username: <input ref={ref} autoFocus
type="text" placeholder="来都来了就留下大名吧" />
</Modal>
注意在React中为驼峰命名:autoFocus
<input>
元素会在重新出现时自动聚焦并拉起输入框,亲测有效。
- 569
-
justjavac
JavaScript
TypeScript