Popper.js: How to close popup when clicking outside

21,754

Solution 1

You can achieve this, by removing event delegation and checking the target on event click by using the .is(), (compare e.target if it equals to the referencing button, otherwise hide the popup)

See fiddle

Added snippet as your code :

also made change in the Popper instance you should pass the current click js-share-cf-btn so the $(e.target) element

$(function() {
  var reference = $('.js-share-cf-btn');
  var popover = $('.js-share-cf-popover');
  popover.hide();

  $(document).on('click touchend', function(e) {
    var target = $(e.target);
    // ne need to reshow and recreate popper when click over popup so return;
    if(target.is(popover)) return;
    if (target.is(reference)) {
      e.preventDefault();

      popover.show();

      var popper = new Popper(target, popover, {
        placement: 'top',
      });
    }else {
      popover.hide();
    }
  });

});
body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

.section {
  background: #fff;
  padding: 20px;
  font-size: 25px;
  text-align: center;
  transition: all 0.2s;
  margin: 0 auto;
  width: 300px;
  margin-bottom: 20px;
}

.share-popover {
  background: red;
  color: white;
  padding: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<div class="section">
  <p>Section 1</p>
  <a href="#" class="js-share-cf-btn">This is the trigger</a>
</div>

<div class="section">
  <p>Section 2</p>
  <a href="#" class="js-share-cf-btn">This is the trigger</a>
</div>

<div class="section">
  <p>Section 3</p>
  <a href="#" class="js-share-cf-btn">This is the trigger</a>
</div>

<div class="share-popover js-share-cf-popover">
  This is the popup
</div>

Solution 2

Something like this should do the trick (by checking the target when you are clicking somewhere):

$(function() {
  var ref = $('.js-share-cf-btn');
  var popover = $('.js-share-cf-popover');
  popover.hide();

  $(document).on('click', function(e) {
    var target = $(e.target);
    if (target.is(ref) || target.is(popover) ) {
      e.preventDefault();
      popover.show();
      var popper = new Popper(ref, popover, {
        placement: 'right',
      });
    }else {
      popover.hide();
    }
  });

});

https://jsfiddle.net/e8aL9tje/

Solution 3

For those using React, I created a gist of an HOC that you can attach to any component to close it when clicked outside:

https://gist.github.com/elie222/850bc4adede99650508aba2090cd5da1

Share:
21,754
Fred K
Author by

Fred K

Web Designer, Front-end developer &amp; Senior Vampire.

Updated on July 16, 2022

Comments

  • Fred K
    Fred K almost 2 years

    I'm using Popper.js to show a popup elment having the class .js-share-cf-popover when clicking elements with class .js-share-cf-btn.

    But I want the popup to close only when I click outside of it. Here my actual code that show the popup:

    var reference = $('.js-share-cf-btn');
    var popover = $('.js-share-cf-popover');
    popover.hide();
    
    $(document).on('click', reference, function(e) {
      e.preventDefault();
    
      popover.show();
    
      var popper = new Popper(reference, popover, {
        placement: 'top',
      });
    });
    

    I found something here but I can't get it works

    Here My jsfiddle

  • Fred K
    Fred K about 6 years
    Hi, when I click inside the popup it closes. I want it close only when clicking outside it.
  • Fred K
    Fred K about 6 years
    Hi, I have multiple button: when click on a button your code shows the popup for every buttons. Check here: jsfiddle.net/tdo2efrs
  • Quentin Roger
    Quentin Roger about 6 years
    Is something like this better ? jsfiddle.net/hovaqnxz Have a great day !
  • Bourbia Brahim
    Bourbia Brahim about 6 years
    @FredK added fiddle and snippet as you discribed , jsfiddle.net/xpvt214o/44982 Does it work ?
  • Fred K
    Fred K about 6 years
    It's an improvement but it remains something strange: click first button then click second button. Result: I get the 2 popups opened, while the first one should be closed.
  • Fred K
    Fred K about 6 years
    You could replace click event with click touch for covering also mobile devices.
  • Fred K
    Fred K about 6 years
    Or maybe click touchend