Home > Blockchain >  .focus() not working, browser keeps focusing the body
.focus() not working, browser keeps focusing the body

Time:05-03

I am currently working on the accessibility for the React modules at our company. Although I am just a hobby webdev I would still really like to solve this.

What's going on is:

We have a module with 6 steps, after clicking a next button it should hop to the top of the next step after being mounted, this does not seem to work in any kind of way and it keeps focusing the body.

What I've tried:

  • I have made use of useRef() and when I log the referred element it works like it should, but when I use focusRef.current.focus() nothing is happening.
  • In document.activeElement within the console it shows body as the active element after the new element is mounted.
  • NerdeFocus (a focus plugin) also shows the body as focussed
  • I also tried just selecting the element with document.getElementById("focusRef") with no result

The code of step 1:

export default function Step1(props) {
  const focusRef = useRef();

  useEffect(() => {
    focusRef.current.focus();
  }, []);

  const {
    reservationItems,
    setStep,
    setSelectedReservation,
    step,
    setAddresses,
    setSelectedAddress,
  } = props;
  const classes = useStyles();

  function onSelectReservation(reservation) {
    setSelectedReservation(reservation);
    setStep(2);
  }
  return (
    <>
      <Typography variant="srOnly">
        Stap 2, kies waar u wilt reserveren
      </Typography>
      <h1 ref={focusRef} className={classes.title}>
        Kies waar u wilt reserveren
      </h1>
      <div className={classes.addressButtons}>
        {reservationItems?.map((reservation, i) => {
          return (
            <div
              key={i}
              className={classes.addressButton}
              onClick={() => onSelectReservation(reservation)}
            >
              <span>{reservation.Description}</span>
              <span>
                {reservation.Street  
                  ' '  
                  reservation.Housenumber  
                  ' '  
                  reservation.City}
              </span>
            </div>
          );
        })}
      </div>

      <Button
        className={classes.buttonPrev}
        variant="contained"
        startIcon={<KeyboardArrowLeftIcon />}
        onClick={() => {
          setStep(step - 1);
          setAddresses([]);
          setSelectedAddress([]);
        }}
      >
        Terug
      </Button>
    </>
  );
}

I hope someone can help me with this issue, thanks in advance Tom.

CodePudding user response:

I can't speak to the React side but in general with single page applications (SPA) when you go to the next step, you want to move the focus to the new heading on the next step. It sounds like that's what you are attempting to do.

With non-React applications, this works fine. Perhaps there's a timing issue with React? Does the element you're trying to move the focus to exist in the DOM when you call focus()?

In some browsers, you can't move the focus to a non-interactive element unless that element has tabindex="-1". I didn't see a tabindex in your sample code so perhaps that's the issue.

For example, if I have:

<h1 id="myID">Step 2 of the process</h1>

and I try to call

document.getElementById('myID').focus();

some browsers will not move the focus to the heading. But if I change my HTML to:

<h1 id="myID" tabindex="-1">Step 2 of the process</h1>

then it works.

  • Related