Popper.js:如何在点击外部时关闭弹出窗口

18

我正在使用Popper.js,以在单击类为.js-share-cf-btn的元素时显示一个具有类.js-share-cf-popover的弹出窗口。

但我希望只有在点击弹出窗口外部时才关闭弹出窗口。这是我的实际代码,用于显示弹出窗口:

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',
  });
});

我在这里发现了一些信息,但我无法使其正常工作。

这是我的jsfiddle


你能提供一个 jsfiddle 吗?这样更容易帮助你。 - Quentin Roger
嗨@QuentinRoger,我在我的问题中添加了jsfiddle。 - Fred K
4个回答

11
您可以通过移除事件委托并使用.is()检查事件点击时的目标来实现此目的(比较e.target是否等于引用按钮,否则隐藏弹出窗口)。
请参见fiddle
将代码添加如下:
还需要更改Popper实例,您应该传递当前单击的js-share-cf-btn以获取$(e.target)元素。
$(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>


嗨,当我点击弹出窗口内部时,它会关闭。我希望只有在点击窗口外部时才关闭它。 - Fred K
1
@FredK根据您的描述添加了fiddle和snippet,https://jsfiddle.net/xpvt214o/44982/。它能正常工作吗? - Bourbia Brahim
1
你可以将 click 事件替换为 click touch,以覆盖移动设备。 - Fred K
1
或者是 click touchend - Fred K

3

这样做应该能实现目的(通过在单击某处时检查目标):

$(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/


嗨,我有多个按钮:当单击一个按钮时,您的代码会为每个按钮显示弹出窗口。请查看此处:https://jsfiddle.net/tdo2efrs/ - Fred K
这样的代码更好吗?https://jsfiddle.net/hovaqnxz/ 祝你有美好的一天! - Quentin Roger
这是一个改进,但仍然有些奇怪:先点击第一个按钮,然后再点击第二个按钮。结果:我得到了两个弹出窗口,而第一个应该被关闭。 - Fred K

0
我找到了一个非常简单的解决方案。
jQuery版本
<div class="Popper">
    <div class="stopPropagation">
        <p>Clicking on me won't close the Popper</p>
    </div>
</div>

$('.stopPropagation').on('click touchend', function(e) {
    e.stopPropagation()
})

由于点击事件不会向上冒泡到 Popper,因此单击时不会关闭 Popper。

React 版本

<Popper>
    {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events */}
    <div onClick={e => e.stopPropagation()} role="none">
        <p>Clicking on me won't close the Popper</p>
    </div>
</Popper>

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接