允许在 div 获得焦点时对其中的按钮进行标签导航。

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

Allow tab navigation for a button within a div. If the div is focussed?

问题

我有一个类似这样的组件:(Code Sandbox: https://codesandbox.io/s/boring-platform-1ry6b2?file=/src/App.js
绿色部分是 div。这是我的代码:

import { useState } from "react";
import "./styles.css";

export default function App() {
  const [insideApp, setInsideApp] = useState(false);
  return (
    <div onFocus={() => setInsideApp(true)} onBlur={() => setInsideApp(false)}>
      <div className="App">
        <input className="input" />
        {insideApp && <button>Show Button</button>}
      </div>
      <p>Out of Box content</p>
    </div>
  );
}
/* css */
.App {
  display: flex;
  border: 2px solid aqua;
  align-items: center;
  column-gap: 2vw;
  padding: 2rem;
}

.App:focus-within {
  border: 2px solid lime;
}

.input {
  flex: auto;
}

理想情况下,我希望通过按Tab键导航到按钮时,它应该像下面显示的那样突出显示:

然而,由于我有条件地呈现按钮,我失去了焦点。有人能帮我想出一些创新的方法来实现相同的效果吗?我希望在焦点位于 div 内时,div 变为绿色,然后执行一个选项卡导航,以便它能检测输入和按钮。

另外,我希望只有在焦点位于 div 内时才显示按钮。

英文:

I am having a component like this: (Code Sandbox: https://codesandbox.io/s/boring-platform-1ry6b2?file=/src/App.js)
允许在 div 获得焦点时对其中的按钮进行标签导航。

The green part is div. Here's my code:

import { useState } from &quot;react&quot;;
import &quot;./styles.css&quot;;

export default function App() {
  const [insideApp, setInsideApp] = useState(false);
  return (
    &lt;div onFocus={() =&gt; setInsideApp(true)} onBlur={() =&gt; setInsideApp(false)}&gt;
      &lt;div className=&quot;App&quot;&gt;
        &lt;input className=&quot;input&quot; /&gt;
        {insideApp &amp;&amp; &lt;button&gt;Show Button&lt;/button&gt;}
      &lt;/div&gt;
      &lt;p&gt;Out of Box content&lt;/p&gt;
    &lt;/div&gt;
  );
}

/* css */
.App {
  display: flex;
  border: 2px solid aqua;
  align-items: center;
  column-gap: 2vw;
  padding: 2rem;
}

.App:focus-within {
  border: 2px solid lime;
}

.input {
  flex: auto;
}

What I want ideally is when I navigate to the button through tab it should get highlighted as shown below:

允许在 div 获得焦点时对其中的按钮进行标签导航。

However since I am rendering the button conditionally I am losing focus. Can someone help me come up with some innovative idea to achieve the same? I want the div to change to lime when its focussed and then do a tab navigation such that it detects input as well as button.

Also I want button to be only shown when focus is within the div.

答案1

得分: 1

查看 SyntheticEvents https://reactjs.org/docs/events.html

有两个事件 onMouseEnteronMouseLeave,可以使用这两个事件来高亮显示 div 并隐藏按钮。

<div
      onMouseEnter={() => setInsideApp(true)}
      onMouseLeave={() => setInsideApp(false)}
    >
      <div className="App">
        {insideApp ? (
          <div>
            <input className="input" />

            <button>Show Button</button>
          </div>
        ) : null}
      </div>
      <p>Out of Box content</p>
    </div>
英文:

Have look to SyntheticEvents https://reactjs.org/docs/events.html

There are two events onMouseEnter and onMouseLeave to you use these two events for highlighting the div and hiding the button.

&lt;div
      onMouseEnter={() =&gt; setInsideApp(true)}
      onMouseLeave={() =&gt; setInsideApp(false)}
    &gt;
      &lt;div className=&quot;App&quot;&gt;
        {insideApp ? (
          &lt;div&gt;
            &lt;input className=&quot;input&quot; /&gt;

            &lt;button&gt;Show Button&lt;/button&gt;
          &lt;/div&gt;
        ) : null}
      &lt;/div&gt;
      &lt;p&gt;Out of Box content&lt;/p&gt;
    &lt;/div&gt;

答案2

得分: 1

你可以使用纯CSS来处理整个过程:

.App {
  display: flex;
  border: 2px solid aqua;
  align-items: center;
  column-gap: 2vw;
  padding: 2rem;
}

.App:focus-within {
  border: 2px solid lime;
}

.App button {
  display: none;
  pointer-events: none;
}
.App:focus-within button {
  display: flex;
  pointer-events: auto;
}

.input {
  flex: auto;
}

解释:

  1. 使用 :focus-within 来有条件地显示按钮。
  2. button 元素禁用指针事件并默认隐藏它,以防止交互。
  3. :focus-within 处于活动状态时,启用指针事件并显示按钮。
英文:

You could use plain CSS to handle all the process:

import { useState } from &quot;react&quot;;
import &quot;./styles.css&quot;;

export default function App() {
  // const [insideApp, setInsideApp] = useState(false);
  return (
    &lt;div&gt;
      &lt;div
        className=&quot;App&quot;&gt;
        &lt;input className=&quot;input&quot; /&gt;
        &lt;button&gt;Show Button&lt;/button&gt;
      &lt;/div&gt;
      &lt;p&gt;Out of Box content&lt;/p&gt;
    &lt;/div&gt;
  );
}

CSS:

.App {
  display: flex;
  border: 2px solid aqua;
  align-items: center;
  column-gap: 2vw;
  padding: 2rem;
}

.App:focus-within {
  border: 2px solid lime;
}


.App button {
  display: none;
  pointer-events: none;
}
.App:focus-within button {
  display: flex;
  pointer-events: auto;
}

.input {
  flex: auto;
}

Explanation:

  1. use :focus-within to conditionnaly display the button
  2. disable cursor events for the button element and hide it as default to prevent interactions
  3. enable cursor events and display the button when :focus-within is active

huangapple
  • 本文由 发表于 2023年3月9日 19:57:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/75684288.html
匿名

发表评论

匿名网友

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

确定