反应动态的tabindex创建

tha*_*mmi 5 html javascript tabindex reactjs

我正在寻找一种tabindex为React应用程序中的每个元素动态创建的方法。有多个组件包含要创建tabindexfor的输入元素,但我不确定如何协调它们并避免碰撞。

我的React应用程序由包含输入元素的多个表组成。在运行时,用户可以扩展表以创建其他输入元素。我想更改用户通过这些输入进行制表的方向,但是我不确定如何tabindex为每个元素生成一个。

到目前为止,我想到的方法是:

  • 每个表都有一个固定的偏移量(但是我不知道单个表中可能有多少输入,并且tabindex应该保持在32767以下,所以我不能只假设巨大的差距)
  • tabindex偏移量传递到表并tabindex从React对象获取使用量以计算下一个偏移量(在我看来,这将破坏模块化并难以实现)
  • tabindex通过全局状态跟踪下一个状态(hacky,并且在扩展表时可能会中断)
  • tabindex通过dom树跟踪下一个(不知道如何实现)

是否有tabindex我所缺少的创作工具或惯例?

Tha*_*ara 6

不知道你有没有想过这个。但是这里有一个技巧可以使用。

您不需要为tabindex表格中的每个单元格设置不同的单元格来进行所需的选项卡导航。您只需要tabindex表中的每一列都不同。您可以tabindex对同一列中的每个单元格重复相同的操作。因为 whentabindex相同,浏览器只是使用 HTML 元素顺序来决定下一个控件,这就是我们在这种情况下需要的。因此tabindex,表的分配将是这样的。

1   2   3   4
1   2   3   4
1   2   3   4
1   2   3   4
Run Code Online (Sandbox Code Playgroud)

这是一个重大的胜利。因为对于 10X10 表,我们不需要 100 个不同的选项卡索引。我们只需要 10 个索引就可以做到。

这是一个用 React 演示这个想法的小例子。你可以运行它看看。

1   2   3   4
1   2   3   4
1   2   3   4
1   2   3   4
Run Code Online (Sandbox Code Playgroud)
// Table
class Table extends React.Component {

  generateRows(){
    const offset = this.props.tabIndexOffSet;
    const cols = this.props.cols;
    const data = this.props.data;

    return data.map(function(item) {
        const cells = cols.map(function(colData, index) {
          return (
            <td key={colData.key}>
              <input type="text"
               value={item[colData.key]}
               tabIndex={offset+index} />
            </td>
          );
        });
        return (<tr key={item.id}> {cells} </tr>);
    });
   }

  generateHeaders() {
    var cols = this.props.cols;
    return (
      <tr>
        {
          cols.map(function(colData) {
            return <th key={colData.key}> {colData.label} </th>;
          })
        }
      </tr>
    );
  }

  render(){
    const headerComponents = this.generateHeaders();
    const rowComponents = this.generateRows();;

    return (
      <table>
          <thead> {headerComponents} </thead>
          <tbody> {rowComponents} </tbody>
      </table>
    );
  }
}

// App
class App extends React.Component{

  constructor(){
    super();
    this.state = { 
      cols: [
          { key: 'firstName', label: 'First Name' },
          { key: 'lastName', label: 'Last Name' }
      ],
      data: [
          { id: 1, firstName: 'John', lastName: 'Doe' },
          { id: 2, firstName: 'Clark', lastName: 'Kent' },
          { id: 3, firstName: 'Tim', lastName: 'Walker' },
          { id: 4, firstName: 'James', lastName: 'Bond' }
      ]
    }
  }
  
  render () {
    return (
      <div>
        <Table
          tabIndexOffSet={1}
          cols={this.state.cols}
          data={this.state.data}/>
        <Table
          tabIndexOffSet={3}
          cols={this.state.cols}
          data={this.state.data}/>
      </div>
    );
  }
}


// Render
ReactDOM.render(
  <App/>,
  document.getElementById('container')
);
Run Code Online (Sandbox Code Playgroud)

如果使用这种方法可以管理列数,我建议您使用第一个选项,为每个表分配不同的偏移量(也在上面的示例中说明)。如果列数是固定的,那么这将很容易。即使不是,您也可以尝试根据您的用例使用固定的硬编码偏移量来保持一些合理的间隙。

如果这不起作用,您可以做的下一件事是尝试从您的数据计算偏移值。我假设您将拥有由该表表示的某种数据,例如对象数组或数组数组,可能处于您的应用程序状态。因此,您可以根据这些数据得出表的偏移量。如果您正在使用像 Redux 这样的状态管理库,那将非常容易,我建议您查看reselect,它可以用于计算 Redux 中的派生状态。

希望这可以帮助!