简体   繁体   English

在点击外部弹出窗口隐藏Bootstrap Popover

[英]Hiding Bootstrap Popover on Click Outside Popover

I'm trying to hide the Bootstrap Popover when the user clicks anywhere outside the popover. 当用户点击弹出窗口外的任何地方时,我正试图隐藏Bootstrap Popover。 (I'm really not sure why the creators of Bootstrap decided not to provide this functionality.) (我真的不确定为什么Bootstrap的创建者决定不提供这种功能。)

I found the following code on the web but I really don't understand it. 在网上找到了以下代码但我真的不明白。

// Hide popover on click anywhere on the document except itself
$(document).click(function(e) {
    // Check for click on the popup itself
    $('.popover').click(function() {
        return false; // Do nothing
    });  
    // Clicking on document other than popup then hide the popup
    $('.pop').popover('hide');  
});

The main thing I find confusing is the line $('.popover').click(function() { return false; }); 我觉得困惑的主要是$('.popover').click(function() { return false; });$('.popover').click(function() { return false; }); . Doesn't this line add an event handler for the click event? 这行不为click事件添加事件处理程序吗? How does that prevent the call to popover('hide') that follows from hiding the popover? 这是如何阻止popover('hide')的调用?

And has anyone seen a better technique? 谁有人见过更好的技术?

Note: I know variations of this question has been asked here before, but the answers to those questions involve code more complex than the code above. 注意:我之前已经在这里询问过这个问题的变体,但这些问题的答案涉及的代码比上面的代码更复杂。 So my question is really about the code above 所以我的问题是关于上面的代码

I made http://jsfiddle.net/BcczZ/2/ , which hopefully answers your question 我做了http://jsfiddle.net/BcczZ/2/ ,希望能回答你的问题

Example HTML 示例HTML

<div class="well>
    <a class="btn" data-toggle="popover" data-content="content.">Popover</a>
    <a class="btn btn-danger bad">Bad button</a>
</div>

JS JS

var $popover = $('[data-toggle=popover]').popover();

//first event handler for bad button
$('.bad').click(function () {
    alert("clicked");
});


$(document).on("click", function (e) {
    var $target = $(e.target),
    var isPopover = $target.is('[data-toggle=popover]'),
        inPopover = $target.closest('.popover').length > 0

    //Does nothing, only prints on console and wastes memory. BAD CODE, REMOVE IT
    $('.bad').click(function () { 
        console.log('clicked');
        return false;
    });

    //hide only if clicked on button or inside popover
    if (!isPopover && !inPopover) $popover.popover('hide');
});

As I mentioned in my comment, event handlers don't get overwritten, they just stack. 正如我在评论中提到的,事件处理程序不会被覆盖,它们只是堆叠。 Since there is already an event handler on the .bad button, it will be fired, along with any other event handler 由于.bad按钮上已有一个事件处理程序,因此它将与任何其他事件处理程序一起触发

Open your console in the jsfiddle, press 5 times somewhere on the page (not the popover button) and then click bad button you should see clicked printed the same amount of times you pressed 在jsfiddle中打开你的控制台,在页面的某个地方按下5次(不是弹出按钮)然后点击bad button你应该看到点击打印的次数与你按下的次数相同

Hope it helps 希望能帮助到你


PS: If you think about it, you already saw this happening, especially in jQuery. PS:如果你考虑一下,你已经看到了这种情况,尤其是在jQuery中。 Think of all the $(document).ready(...) that exist in a page using multiple jquery plugins. 想想使用多个jquery插件在页面中存在的所有$(document).ready(...) That line just registers an event handler on the document's ready event 该行只是在文档的ready事件上注册一个事件处理程序

I just did a more event based solution. 我刚刚做了一个基于事件的解决方案。

var $toggle = $('.your-popover-button');
$toggle.popover();

var hidePopover = function() {
    $toggle.popover('hide');
};

$toggle.on('shown', function () {
    var $popover = $toggle.next();
    $popover.on('mousedown', function(e) {
        e.stopPropagation();
    });
    $toggle.on('mousedown', function(e) {
        e.stopPropagation();
    });
    $(document).on('mousedown',hidePopover);
});

$toggle.on('hidden', function () {
    $(document).off('mousedown', hidePopover);
});

short answer insert this to bootstrap min.js 简短的回答将此插入bootstrap min.js

when popout onblur will hide popover 当popout onblur将隐藏popover
when popout more than one, older popover will be hide 当popout不止一个时,旧的popover将被隐藏

$count=0;$(document).click(function(evt){if($count==0){$count++;}else{$('[data-toggle="popover"]').popover('hide');$count=0;}});$('[data-toggle="popover"]').popover();$('[data-toggle="popover"]').on('click', function(e){$('[data-toggle="popover"]').not(this).popover('hide');$count=0;});

None of the above solutions worked 100% for me because I had to click twice on another, or the same, popover to open it again. 以上解决方案都没有为我100%工作,因为我不得不在另一个上点击两次,或者相同,弹出以再次打开它。 I have written the solution from scratch to be simple and effective. 我从头开始编写解决方案简单有效。

   $('[data-toggle="popover"]').popover({
        html:true,
        trigger: "manual",
        animation: false
    });

    $(document).on('click','body',function(e){
        $('[data-toggle="popover"]').each(function () {
            $(this).popover('hide');
        });

        if (e.target.hasAttribute('data-toggle') && e.target.getAttribute('data-toggle') === 'popover') {
            e.preventDefault();
            $(e.target).popover('show');
        }
        else if (e.target.parentElement.hasAttribute('data-toggle') && e.target.parentElement.getAttribute('data-toggle') === 'popover') {
            e.preventDefault();
            $(e.target.parentElement).popover('show');
        }
    });

My solution, works 100%, for Bootstrap v3 我的解决方案,100%工作,用于Bootstrap v3

$('html').on('click', function(e) {
    if(typeof $(e.target).data('original-title') !== 'undefined'){
         $('[data-original-title]').not(e.target).popover('hide');
    }

    if($(e.target).parents().is('[data-original-title]')){
         $('[data-original-title]').not($(e.target).closest('[data-original-title]')).popover('hide');
    }

    if (typeof $(e.target).data('original-title') == 'undefined' &&
!$(e.target).parents().is('.popover.in') && !$(e.target).parents().is('[data-original-title]')) {
        $('[data-original-title]').popover('hide');
    }
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM