在 mousedown 事件中让 input 标签获取焦点的问题

Posted 在厕所喝茶

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在 mousedown 事件中让 input 标签获取焦点的问题相关的知识,希望对你有一定的参考价值。

问题

我们先来看如下的代码:

<body>
  <button id="button">点击</button>
  <div class="container"></div>
</body>
const buttonElement = document.querySelector("#button");
const containerElement = document.querySelector(".container");
buttonElement.addEventListener("mousedown", () => 
  const inputElement = document.createElement("input");
  containerElement.appendChild(inputElement);
  inputElement.focus();
);

从上面的代码中,我们可以看出,代码的主要目的是在button按钮触发mousedown事件的时候,动态生成一个input标签,添加到页面中,并且input标签需要获取到焦点。

但是事实上并没有达到我们的预期,input标签并没有能够获取得到焦点

原因分析

首先我第一时间想到的就是,是不是有其他元素在inputElement.focus()这行代码执行之后,获取到了焦点,导致input标签失焦了呢?而且页面跟我有交互的就只有button按钮了。

所以,很有可能是因为button按钮得到了焦点,导致input标签失去了焦点

于是,我给button按钮添加了一个focus事件来验证我的猜想:

const buttonElement = document.querySelector("#button");
const containerElement = document.querySelector(".container");

buttonElement.addEventListener("focus", () => 
  console.log("focus");
);

buttonElement.addEventListener("mousedown", () => 
  const inputElement = document.createElement("input");
  containerElement.appendChild(inputElement);
  inputElement.focus();
  console.log("mousedown");
);

最终输出的结果是:mousedown -> focus

所以input标签获取不到焦点的原因就是:用户点击button按钮会使button按钮得到焦点,并且发生的时机是在mousedown事件之后,导致input标签无法得到焦点

解决方案

方案一:等待button按钮获取得到焦点之后在让input标签获取焦点

buttonElement.addEventListener("mousedown", () => 
  // ...
  setTimeout(() => 
    inputElement.focus();
  , 0);
);

可以采用定时器延迟input标签获取焦点的时机

方案二:阻止input标签获取焦点的默认事件

buttonElement.addEventListener("mousedown", (event) => 
  event.preventDefault();
  // ...
  inputElement.focus();
);

event.preventDefault()可以阻止button按钮的focus事件发生,也就是不会让按钮得到焦点

方案三:使用click事件

buttonElement.addEventListener("focus", () => 
  console.log("focus");
);
buttonElement.addEventListener("mousedown", () => 
  console.log("mousedown");
);
buttonElement.addEventListener("click", () => 
  console.log("click");
);

上面代码的执行结果为:mousedown -> focus -> click

click事件是发生在focus事件之后的,所以可以在click事件中让input标签获取焦点

以上是关于在 mousedown 事件中让 input 标签获取焦点的问题的主要内容,如果未能解决你的问题,请参考以下文章

解决如何在点击按钮时,不触发input的失去焦点事件

php超链接标签事件都有哪些

WPF如何将mousedown(命令/动作)绑定到标签

vue

鼠标事件执行顺序

在 mousedown 事件中添加的 Mousemove 事件在鼠标不移动时不断触发