2

我在这里有一个代码沙箱,它演示了我想要做什么。

当用户按下按钮时,会显示文本输入并获得焦点。

为此,我使用 ref 并为其提供焦点,这很好:

  //When user clicks button, show input
  const handleClick = useCallback(() => {
    setShowInput(true);
  }, []);  

  useEffect(() => {
    if (showInput && inputRef.current) {
      inputRef.current.focus();
    }
  }, [showInput]);

当用户从文本字段中跳出时,我希望焦点回到那个按钮上。

在我在这里的代码中,我也通过使用 ref 并将焦点放在按钮上来实现这一点。

  //When user exits input, unshow input
  //Also, need to tab to button if it was a tab button press. 
  const handleInputBlur = useCallback(() => {
    setShowInput(false);
    if (buttonRef.current) {
      buttonRef.current.focus();
    }
  }, []);

然而,问题是如果用户使用他们的鼠标点击另一个按钮,那么焦点仍然被赋予触发按钮。

我想做的是为这些组件定义一些标签顺序,即:

TextField => 触发按钮 => 其他按钮

但是,我不想将选项卡索引硬编码到我的组件中,因为这可能无法很好地与整个应用程序一起使用?

对此有优雅的反应解决方案吗?

4

2 回答 2

1

最好的答案是,如果您希望您的选项卡顺序为 TextField => Trigger Button => Other Button,则按该顺序呈现 HTML。

然后,您可以使用 CSS 更改视觉顺序。

.container {
 display: flex; 
 border: solid 1px black; 
}

 button {
 margin: 1em; 
 padding: 1em; 
 }  
 
 .order-1 {
    order: 1; 
 }
  
 .order-2 {
    order: 2; 
 } 
 
 .order-3 {
    order: 3; 
 }
 
 .order-4 {
    order: 4; 
 }
<div class = "container"> 
  <button class ="order-4"> 1</button> 
  <button class = "order-2"> 2</button> 
  <button class = "order-3"> 3</button> 
  <button class ="order-1"> 4</button> 
</div> 

于 2019-11-02T06:53:20.737 回答
0

我喜欢 dwjohnston 的简单回答。如果需要更复杂的东西,我们可以考虑react-tabindex插件。

useTabIndex 返回一个值以传递给您选择的元素上的 tabIndex 属性。如果包装在活动祖先中,则该 tabIndex 值将自动设置为 -1,使元素不可选项卡。

$ npm install react-tabindex

import { useTabIndex } from 'react-tabindex';
 
function ExampleButton() {
  const tabIndex = useTabIndex();
 
  return <button tabIndex={tabIndex}>Click here!</button>;
}
于 2021-12-02T16:17:37.853 回答