Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Focus on div without click in React to enable keyboard navigation on a module

Tags:

focus

reactjs

I am coding an image gallery from scratch in React, when clicking on an image, a modal pops up (separate component from my gallery component). I want to navigate between the pictures with left and right arrow, not just with the added arrows on the screen (onclick) but at the moment it only focuses on the modal when I click on it once, then I can navigate with the keyboard too (onKeyDown).

I have added tabIndex="0" to my div, but I still need to click on the div once to focus on it.

<div tabIndex="0" onKeyDown={(event) => this.onKeyNavigation(event, ImageUrl, currentIndex, ImageUrls)}>

onKeyNavigation = (event, ImageUrl, currentIndex, ImageUrls) => {

if ((event.keyCode) === 39) {
    this.props.loadNext(ImageUrl, currentIndex, ImageUrls)
  }
  else if ((event.keyCode) === 37) {
    this.props.loadPrevious(ImageUrl, currentIndex, ImageUrls)
  }
  else if ((event.keyCode) === 27) {
    this.props.onClose()
  }
 }
like image 345
Gabriella Csernus Avatar asked Nov 08 '22 00:11

Gabriella Csernus


1 Answers

You'll need to fire a focus() event on the <div> you want to have focus after it has rendered.

The easiest way to do this is to use React's built-in lifecycle methods. First, create a ref for the element you want to have focus (in this case, the div listening for keyDown events). Then, you can call focus() on that node in your component's componentDidMount() method:

class ImageGallery extends React.Component {
    construtor(){
        super();

        // Create the ref in the constructor
        this.focusRef = React.createRef();
    }

    /* your other methods here */

    componentDidMount(){
        // Focus on the rendered div using the DOM focus() method
        this.focusRef.focus();
    }

    render(){
        // Set the ref in your render() method
        return(<div ref={this.focusRef} onKeyDown={this.handle}></div>);
    }
}
like image 73
dcastrodale Avatar answered Nov 15 '22 06:11

dcastrodale