如何检测 div 上的焦点丧失

huangapple go评论65阅读模式
英文:

How to detect focus out on div

问题

我正在处理辅助功能问题,因此正在使用TAB键测试我的应用程序。我希望在以下div元素失去焦点时执行某些操作。

所以在我的想象中,这个onBlur函数应该只在我按下TAB键移动到按钮2并转移到按钮3时触发。但是这个onBlurdiv内的每次TAB点击都被调用。为什么会发生这种情况?

我应该怎么做才能在我移出这个div后才触发这个函数?所以在按下TAB键移动到按钮2并转移到按钮3后,应该触发这个函数。

英文:

I am working on accessibility, so I am testing my app using TAB key. I would like to do something when following div element loses focus.

So in my imagination this onBlur function should only fire when I would click TAB key on button 2 and move to button 3. But this onBlur is call on every TAB click in inside this div. Why this is happening?

What should I do to fire function only when I will be outside of this div. So after click TAB key on button 2 and move to button 3, this function should be fired

export default function App() {
  return (
    <>
      <div onBlur={() => console.log('Blur')} style={{ padding: '20px', border: '1px solid #000'}} tabIndex={0}>
        <button>1</button>
        <button>2</button>
      </div>
      <button>3</button>
      </>
  );
}

答案1

得分: 2

你可以简单地利用onBlur回调中可用的e.relatedTarget来检测以下情况:

  1. 相关目标是当前目标<div>本身,或者
  2. 相关目标是当前目标<div>的后代,使用Node.contains方法

如果以上两个条件都不满足,那么你可以有条件地调用所需的逻辑:

<div
  onBlur={(e) => {
    if (
      e.relatedTarget !== e.currentTarget &&
      !e.currentTarget.contains(e.relatedTarget)
    ) {
      console.log("Blur");
    }
  }}
  tabIndex={0}
>
  {/* 这里是内容 */}
</div>

我制作了一个概念验证的Codesandbox,以演示上述代码,但我用<button>替换成<input>以进行更可视化的测试:

如何检测 div 上的焦点丧失

英文:

You can simply take advantage of the e.relatedTarget that is available in the onBlur callback to detect if:

  1. The related target is the current target <div> itself, or
  2. The related target is a descendant of the current target <div> by using the Node.contains method

If neither conditions are met, then you conditionally invoke the necessary logic:

<div
  onBlur={(e) => {
    if (
      e.relatedTarget !== e.currentTarget &&
      !e.currentTarget.contains(e.relatedTarget)
    ) {
      console.log("Blur");
    }
  }}
  tabIndex={0}
>
  {/* Content here */}
</div>

I have made a proof-of-concept Codesandbox to demonstrate the code above, but I've swapped out the <button> with <input> just for a more visual test:

如何检测 div 上的焦点丧失

答案2

得分: -1

If you only want onBlur to fire when leaving button 2 you can just move the onBlur to button 2

return (
  <>
    <div style={{ padding: '20px', border: '1px solid #000' }} tabIndex={0}>
      <button>1</button>
      <button onBlur={() => console.log('Blur')}>2</button>
    </div>
    <button>3</button>
  </>
);
英文:

If you only want onBlur to fire when leaving button 2 you can just move the onBlur to button 2

return (
&lt;&gt;
  &lt;div style={{ padding: &#39;20px&#39;, border: &#39;1px solid #000&#39; }} tabIndex={0}&gt;
    &lt;button&gt;1&lt;/button&gt;
    &lt;button onBlur={() =&gt; console.log(&#39;Blur&#39;)}&gt;2&lt;/button&gt;
  &lt;/div&gt;
  &lt;button&gt;3&lt;/button&gt;
&lt;/&gt;

);

huangapple
  • 本文由 发表于 2023年2月6日 06:24:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/75355927.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定