0

I have reactJs app and I have made a custom dropDown with a div that I set an onClick attribute to open dropDown and close it. but also I want to close it when the user clicks to another part of the site.

 <div
    onClick={() => setNoneQuote(noneQuote ? false : true)}
    className="selected-drop-down"
 >
    <span className="dropDownText">{selectedQuoteCurrency}</span>
    <img
      className="dropDownIcon"
      src={require("../assets/image/arrow/dropDown-Arrow.png")}
      width="15px"
      alt="arrow"
    />
 </div>

I try onMouseDown instead of onClick according to this answer ==> stackoverflow ,but I don't know why it doesn't work for me :(

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
hossein fti
  • 900
  • 1
  • 6
  • 12

2 Answers2

1
const dropdownElement= document.querySelector("choose an id or a specific class")
window.onclick = function(event) {
  if (event.target !== dropdownElement) {
    dropdownElement.style.display = "none"; // or any other function that you want to call
  }
}

this may not be the exact code to fix your problem but you can use the logic

Deniz Karadağ
  • 751
  • 3
  • 8
  • I did this logic but I was faced with a problem that when the component **didmount** for the first time everything is okay and dropDown opened and when click over there it closed, but for the second time, the dropdown didn't open because the state not to change to true. – hossein fti Feb 08 '22 at 12:26
1

You could do it in different ways, but I will show you solution that I used in one of my projects.

So, I used <header> and <main> tags where I had all my Components. And in those tags i used eventListener with a callback function, like this:

<header onClick={handleClick}>
      <Nav />
      <Greeting />
      <Sidebar />
</header>

and

<main onClick={handleClick}>
          <Description />
          <Icons />
          <Prices />
          <Gallery />
          <NecessaryInfo />
          <Location />
          <GalleryModal />
          <ConditionsModal />
        </main>

In a callback function handleClick I checked where user could click and to do that I used next logic of pure JS:

!e.target.classList.contains("menu-open") &&
  !e.target.classList.contains("menu-links") &&
   !e.target.parentElement.classList.contains("menu-links") &&
  !e.target.parentElement.parentElement.classList.contains("menu-links") &&
  closeSidebar();

Function closeSidebar() is simple:

const closeSidebar = () => {
setIsSidebarOpen(false)};

In your code instead of using setNoneQuote(noneQuote ? false : true) you could also use: setNoneQuote(!noneQuote). Exclamation mark before value always will change it to the oposite.

Double-w-B
  • 54
  • 1
  • 4