簡體   English   中英

如何在功能組件中將下一個輸入集中在按下回車鍵上? (TAB 行為)

[英]How to focus next input on pressing enter, in functional components? (TAB behavior)

我想實現 TAB 行為,但要按 ENTER。

這是我嘗試解決它的嘗試,但由於未使用Refs而無法正常工作。

我的想法是在每個輸入中輸入 state,接下來應該關注哪個元素,然后 Enter keyup 事件處理程序將該值設置為新的焦點字段。

我看過使用useHook的例子,但我不知道如何使用它,而不是為每個輸入發送大量的useState

這是下面代碼的沙盒

import React, { useState, useEffect } from "react";

function Form(props) {
  // Holds the ID of the focused element
  const [focusedElementId, setFocusedElementId] = useState("input-one");

  // The actual focusing, after each re-render
  useEffect(() => {
    document.getElementById(focusedElementId).focus();
  }, []);

  useEffect(() => {
    console.log("STATE:", focusedElementId);
  }, [focusedElementId]);

  // When Enter is pressed, set the focused state to the next element ID provided in each input
  function handleKeyUp(e) {
    e.which = e.which || e.keyCode;
    if (e.which == 13) {
      let nextElementId = e.target.attributes["data-focus"].value;
      console.log(`HANDLER: Enter - focusing ${nextElementId}`);
      setFocusedElementId(nextElementId);
    }
  }

  return (
    <div>
      <div className="form-items" style={{ display: "flex" }}>

        <div className="input-group">
          <label>{"Input One"}</label>
          <br />
          <input
            type={"text"}
            id={"input-one"}
            onKeyUp={handleKeyUp}
            data-focus={"input-two"}
          />
        </div>

        <div className="input-group">
          <label>{"Input Two"}</label>
          <br />
          <input
            type={"text"}
            id={"input-two"}
            onKeyUp={handleKeyUp}
            data-focus={"input-three"}
          />
        </div>

        <div className="input-group">
          <label>{"Input Three"}</label>
          <br />
          <input
            type={"text"}
            id={"input-three"}
            onKeyUp={handleKeyUp}
            data-focus={"input-one"}
          />
        </div>

      </div>
    </div>
  );
}

export default Form;

我設法讓它與refs一起工作。

這是沙盒

它看起來足夠簡單和干凈,但我仍然對你的意見感到好奇。

import React from "react";

function Form() {
  let one = React.createRef();
  let two = React.createRef();
  let three = React.createRef();

  // When Enter is pressed, set the focused state to the next element ID provided in each input
  function handleKeyUp(e) {

    e.which = e.which || e.keyCode;

    // If the key press is Enter
    if (e.which == 13) {
      switch (e.target.id) {
        case "input-one":
          two.current.focus();
          break;
        case "input-two":
          three.current.focus();
          break;
        case "input-three":
          one.current.focus();
          break;

        default:
          break;
      }
    }
  }

  return (
    <div>
      <div className="form-items" style={{ display: "flex" }}>
        <div className="input-group">
          <label>{"Input One"}</label>
          <br />
          <input
            type={"text"}
            id={"input-one"}
            onKeyUp={handleKeyUp}
            ref={one}
          />
        </div>

        <div className="input-group">
          <label>{"Input Two"}</label>
          <br />
          <input
            type={"text"}
            id={"input-two"}
            onKeyUp={handleKeyUp}
            ref={two}
          />
        </div>

        <div className="input-group">
          <label>{"Input Three"}</label>
          <br />
          <input
            type={"text"}
            id={"input-three"}
            onKeyUp={handleKeyUp}
            ref={three}
          />
        </div>
      </div>
    </div>
  );
}

export default Form;

這是一個更具可擴展性的版本; 只需附加在容器元素上:

function onKeyDown(e) {
    if (e.key === 'Enter') {
      const fields =
        Array.from(e.currentTarget.querySelectorAll('input')) ||
        []
      const position = fields.indexOf(
        e.target // as HTMLInputElement (for TypeScript)
      )
      fields[position + 1] && fields[position + 1].focus()
    }
  }

創建了這個鈎子

import  { useCallback, useEffect } from 'react'

export default function useFormTab() {
    const keyDownHandler = useCallback((event: KeyboardEvent) => { 
        const target = event.target as HTMLButtonElement
        if (event.keyCode === 13  && target.nodeName === "INPUT") {
            var form = target.form;
            var index = Array.prototype.indexOf.call(form, event.target);
            // @ts-ignore
            form.elements[index + 2].focus();
            event.preventDefault();
          }
     }, []);

  useEffect(() => {
    
    document.addEventListener("keydown", keyDownHandler);
    return () => document.removeEventListener("keydown", keyDownHandler);
  }, [])
  
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM