7

I used this tutorial to add popups to my webpage. Is there a way to make it so a popup closes when you click outside it/click on a different one.

I've tried adding an invisibleDiv as per this post Close pop up div by clicking outside of it but the popup is still only moving when the button itself is clicked.

https://www.w3schools.com/howto/howto_js_popup.asp

// When the user clicks on div, open the popup
function myFunction() {
  var popup = document.getElementById("myPopup");
  popup.classList.toggle("show");
}
    /* Popup container - can be anything you want */
    .popup {
      position: relative;
      display: inline-block;
      cursor: pointer;
      -webkit-user-select: none;
      -moz-user-select: none;
      -ms-user-select: none;
      user-select: none;
    }
    
    /* The actual popup */
    .popup .popuptext {
      visibility: hidden;
      width: 160px;
      background-color: #555;
      color: #fff;
      text-align: center;
      border-radius: 6px;
      padding: 8px 0;
      position: absolute;
      z-index: 1;
      bottom: 125%;
      left: 50%;
      margin-left: -80px;
    }
    
    /* Popup arrow */
    .popup .popuptext::after {
      content: "";
      position: absolute;
      top: 100%;
      left: 50%;
      margin-left: -5px;
      border-width: 5px;
      border-style: solid;
      border-color: #555 transparent transparent transparent;
    }
    
    /* Toggle this class - hide and show the popup */
    .popup .show {
      visibility: visible;
      -webkit-animation: fadeIn 1s;
      animation: fadeIn 1s;
    }
    
    /* Add animation (fade in the popup) */
    @-webkit-keyframes fadeIn {
      from {opacity: 0;} 
      to {opacity: 1;}
    }
    
    @keyframes fadeIn {
      from {opacity: 0;}
      to {opacity:1 ;}
    }
<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1">
  </head>
  <body style="text-align:center">
    <h2>Popup</h2>
    <div class="popup" onclick="myFunction()">Click me to toggle the popup!
      <span class="popuptext" id="myPopup">A Simple Popup!</span>
    </div>
  </body>
</html>
Joe
  • 107
  • 1
  • 2
  • 7
  • https://stackoverflow.com/questions/152975/how-do-i-detect-a-click-outside-an-element there are some non jquery answers – epascarello Jul 09 '20 at 17:28

3 Answers3

7

Having a global click-handler that checks the clicked element's classList is one way to close the pop-up when clicking outside of it. Here is an example:

const popups = [...document.getElementsByClassName('popup')];

window.addEventListener('click', ({ target }) => {
  const popup = target.closest('.popup');
  const clickedOnClosedPopup = popup && !popup.classList.contains('show');
  
  popups.forEach(p => p.classList.remove('show'));
  
  if (clickedOnClosedPopup) popup.classList.add('show');  
});
/* Popup container - can be anything you want */
.popup {
  position: relative;
  display: inline-block;
  cursor: pointer;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}

/* The actual popup */
.popup .popuptext {
  visibility: hidden;
  width: 160px;
  background-color: #555;
  color: #fff;
  text-align: center;
  border-radius: 6px;
  padding: 8px 0;
  position: absolute;
  z-index: 1;
  bottom: 125%;
  left: 50%;
  margin-left: -80px;
}

/* Popup arrow */
.popup .popuptext::after {
  content: "";
  position: absolute;
  top: 100%;
  left: 50%;
  margin-left: -5px;
  border-width: 5px;
  border-style: solid;
  border-color: #555 transparent transparent transparent;
}

/* Toggle this class - hide and show the popup */
.popup.show .popuptext {
  visibility: visible;
  -webkit-animation: fadeIn 1s;
  animation: fadeIn 1s;
}

/* Add animation (fade in the popup) */
@-webkit-keyframes fadeIn {
  from {opacity: 0;} 
  to {opacity: 1;}
}

@keyframes fadeIn {
  from {opacity: 0;}
  to {opacity:1 ;}
}
<h2>Popup</h2>

<div class="popup">Click me to toggle the popup!
  <span class="popuptext">A Simple Popup!</span>
</div>

<div class="popup">Click me to toggle the popup!
  <span class="popuptext">A Simple Popup!</span>
</div>
Andre Nuechter
  • 2,141
  • 11
  • 19
  • This is great but it doesn't work if I have two popups: var popup = document.getElementById("myPopup"); function myFunction() { popup.classList.toggle("show"); } window.addEventListener('click', ({ target }) => { if (!target.closest('.popup') && popup.classList.contains('show')) myFunction(); }); var popup = document.getElementById("myPopup2"); function myFunction2() { popup.classList.toggle("show"); } window.addEventListener('click', ({ target }) => { if (!target.closest('.popup') && popup.classList.contains('show')) myFunction2(); }); – Joe Jul 09 '20 at 18:29
  • @Joe I updated my answer to work for that case as well. Note that I'm now adding the show class to the container and not the popup. – Andre Nuechter Jul 10 '20 at 18:37
4

Add an onclick to the popup's container and stop event propagation on all internal elements you don't want to trigger the action.

let popup = document.querySelector(".popup");

function toggle(e) {
  e.stopPropagation();
  popup.classList.toggle("hide");
}

function closePopup() {

  if (!popup.classList.contains("hide")) {
    popup.classList.toggle("hide");
  }
}
body {
  margin: 0;
}

.container {
  width: 100vw;
  height: 100vh;
  background: lightgray;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.popup {
  width: 100px;
  height: 100px;
  background: white;
  margin: 0 auto;
}

button {
  position: fixed;
  top: 0;
}

.hide {
  display: none;
}
<div class="container" onclick="closePopup()">
  <div class="popup hide" onclick="event.stopPropagation()"> </div>
  <Button onclick="toggle(event)">Toggle</Button>
</div>
Pavlos Karalis
  • 2,893
  • 1
  • 6
  • 14
0

PHP

<?php       
    echo '<div><a href="#" id="btnshow" onclick="showcontents();">Display Content</a></div>';
    echo '<div id="viewcontent"></div>';
 ?>

Script

Fill the generated content to the inside div

function showcontents()
{
  var content = 'Add dynamic content';
  $('#viewcontent').html(content);
}  

Empty the div content by clicking outside div

$("body").click(function(e) 
{
  var contentlength = $("#viewcontent").text().length;      
  if(contentlength > 0 && e.target.id != 'btnshow'){
     $('#viewcontent').html("");
  }
}
Sreejith N
  • 25
  • 5