skip to Main Content

I have a popup button in my header. I need to make sure that when clicking outside its zone, the popup closes. How can i do this? In the code I’m trying to add remove active classes when clicking on body.active-search but it doesn’t work.

const body = document.querySelector("body");
const searchButton = document.querySelector(".search-button");
const searchPopup = document.querySelector(".search-popup");

if (searchButton) {
  searchButton.addEventListener("click", () => {
    searchPopup.classList.toggle("active");
    searchButton.classList.toggle("active");
    body.classList.toggle("active-search");
  });
}

$(".active-search").click(function() {
  searchPopup.removeClass("active");
  searchButton.removeClass("active");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<header>
  <div class="search-wrapper">
    <button class="search-button">Open Search</button>
    <div class="search-popup"></div>
  </div>
</header>

2

Answers


  1. Similar issue was described here Hide popup by clicking elsewhere

    Basically you have to add a couple of code lines

    $("body").click(function(){
      searchPopup.remove("active");
      searchButton.remove("active");
    });
    
    searchPopup.click(function(e){
      e.stopPropagation();
    });
    
    searchButton.click(function(e){
      e.stopPropagation();
    });
    

    Hope this helps.

    Login or Signup to reply.
  2. On BODY "click" use Event.target.closest("selector") to determine if a click landed on specific elements selectors, if that’s the case do nothing (return from the function); otherwise toggle the "active-search" class on BODY.
    Also, there’s no need to specifically toggle other active classes on elements. Use CSS instead.

    const el = (sel, par) => (par??document).querySelector(sel);
    
    const elSearchButton = el(".search-button");
    const elSearchPopup = el(".search-popup");
    const elBody = el("body");
    
    elSearchButton.addEventListener("click", () => {
      elBody.classList.toggle("active-search");
    });
    
    elBody.addEventListener("click", (evt) => {
      // Do nothing if popup clicked or button
      if (evt.target.closest(".search-button, .search-popup")) return;
      // Else...
      elBody.classList.remove("active-search");
    });
    /*QuickReset*/ * {margin:0; box-sizing: border-box;}
    
    body {
      min-height: 100vh;
    }
    
    .active-search {
      background: #eee;
    }
    
    .search-popup {
      display: none;
      padding: 1rem;
      background: gold;
    }
    
    .active-search .search-popup {
      display: block !important;
    }
    <header>
      <div class="search-wrapper">
        <button type="button" class="search-button">Toggle Search</button>
        <div class="search-popup"><input type="search" placeholder="Search..."></div>
      </div>
    </header>

    See this closely related answer: https://stackoverflow.com/a/70691308/383904

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search