Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React Javascript onclick outside div

logout with svg icon

I am working on a website and currently i am having an svg icon for logout. when icon is clicked an overlay is popped up with signout option. when user clicks on signout it should do certain operation and when user clicks outside div overlay should be hidden. i am failing to achieve this.

i tried to give focus to div by using tabIndex but then signout option is not clickable anymore.

Header.js

 import React, { Component } from "react";
    import ReactDOM from "react-dom";
    class MainHeader extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          logOutShown: false
        };
      }
    render() {
    var guiResult = [];
    if (this.state.logOutShown) {
      guiResult.push(
        <div className="Login__Overlay__Frame">
          <div className="User__Login__Overlay">
          <div className="Login__Content" tabIndex="1" onFocus={this.alerting.bind(this)} onBlur={this.toggleOverlay.bind(this)}>Signout</div>
          </div>
        </div>
      );
    }

    return (
            <div className="Header__Icon">
              <div className="Icons__Log__In" tabIndex="0" onClick={this.validate.bind(this)} onBlur={this.toggleOverlay.bind(this)}/>
              {guiResult}
            </div>
    );
  }

  toggleOverlay(){
    console.log("toggle overlay");
    this.setState({ logOutShown: false});
  }

  validate() {
    console.log("validate:");
    this.setState(
      {
        logOutShown: true
      }
    );
  }
like image 435
user28 Avatar asked Mar 05 '19 11:03

user28


People also ask

How do I detect a click outside an element in React JS?

Detecting an outside click of a functional component Let's build an HTML tooltip by creating a React functional component named InfoBox . The tooltip will appear when the user clicks a button, and it will be closed if the user clicks outside of the tooltip component.

How do you find a click outside of an element?

So, for detecting a click outside an element, it would be best if you add a listener to the whole document element. Consequently, the main loop will go up the DOM from the clicked target element to search if the ancestor of that element belongs to the flyout container.

How do I close a drop down when click outside the React?

We will detect the click event and use it to close the dropdown ui component when the user clicks outside the element scope in React application. To give you the clear picture, we will start with creating a basic app, creating component, design dropdown using custom CSS.

How do I hide the dropdown menu on click outside of the element in React JS?

Here we go: abandon stop propagation, go back to listening to the document object, and use the node. contains API to determine whether a click event happens outside the dropdown menu. If it does, hide the dropdown menu, since we need to use ref to save the DOM node in React in order to use the API.


2 Answers

You can use a well writen library like this one: react-outside-click-handler

example:

import OutsideClickHandler from 'react-outside-click-handler';

function MyComponent() {
  return (
    <OutsideClickHandler
      onOutsideClick={() => {
        alert('You clicked outside of this component!!!');
      }}
    >
      Hello World
    </OutsideClickHandler>
  );
}

Edit:

As I am editing this comment today, a lot of new library bring this feature to your code.

If you use a components library check if an util exists in it. (chakra, mantine, material-ui).

Other solution exists inside hooks libraries like react-use.

like image 199
Alexandre Nicolas Avatar answered Sep 28 '22 02:09

Alexandre Nicolas


Here is a simple example, I'm using React hooks here instead of classes, but you can use classes too..

The main part is the onClick on the container div, if you run the example below and click on the dialog it won't close it, but clicking on the overlay will.

The e.stopPropagation() on the container div is what stops the events on the contents firing the events on the overlay. Instead of using stopPropagation, another option is checking the target & currentTarget inside the overlay onClick..

const {useState} = React;


function Overlay(props) {
  const {contents} = props;
  const [open, setOpen] = useState(true);
  if (open) {
    return <div className="overlay" onClick={() => setOpen(false)}>
      <div onClick={(e) => {
        //stop clicks getting to the overlay
        e.stopPropagation();
      }}className="overlay-container">
        {contents()}
      </div>
    </div>
  }
  return null;
}


ReactDOM.render(<React.Fragment>
  This is some content to overlay.<br/>
  for testing..
  <Overlay contents={() =>
    <div>This is the contents, clicking here wont effect ovelay</div>
  }/>
</React.Fragment>, document.querySelector('#mount'));
.overlay {
  position: fixed;
  background-color: rgba(100,100,100,0.5);
  left: 0;
  top: 0;
  bottom: 0;
  right: 0;
}

.overlay-container {
  border: 1px solid black;
  background-color: white;
  position: absolute;
  top: 30px;
  left: 30px;
  width: 200px;
  height: 80px;
  padding: 5px;
}
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

<div id="mount"></div>
like image 39
Keith Avatar answered Sep 28 '22 01:09

Keith