twitter-bootstrap 在弹出框外单击时隐藏 Bootstrap 弹出框
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17842121/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Hiding Bootstrap Popover on Click Outside Popover
提问by Jonathan Wood
I'm trying to hide the Bootstrap Popover when the user clicks anywhere outside the popover. (I'm really not sure why the creators of Bootstrap decided not to provide this functionality.)
当用户单击弹出框外的任何地方时,我试图隐藏 Bootstrap 弹出框。(我真的不知道为什么 Bootstrap 的创建者决定不提供这个功能。)
I found the following code on the webbut 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; });. Doesn't this line add an event handler for the click event? How does that prevent the call to popover('hide')that follows from hiding the popover?
我觉得令人困惑的主要事情是 line $('.popover').click(function() { return false; });。这行不是为 click 事件添加了一个事件处理程序吗?这如何防止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
注意:我知道这里之前已经问过这个问题的变体,但是这些问题的答案涉及比上面的代码更复杂的代码。所以我的问题实际上是关于上面的代码
采纳答案by Dogoku
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 .badbutton, 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 buttonyou should see clicked printed the same amount of times you pressed
在 jsfiddle 中打开您的控制台,在页面上的某处(不是弹出按钮)按 5 次,然后单击bad button您应该看到 clicked 打印的次数与您按下的次数相同
Hope it helps
希望能帮助到你
P.S:If you think about it, you already saw this happening, especially in jQuery.
Think of all the $(document).ready(...)that exist in a page using multiple jquery plugins. That line just registers an event handler on the document's readyevent
PS:仔细想想,你已经看到这种情况发生了,尤其是在 jQuery 中。想想$(document).ready(...)使用多个 jquery 插件的页面中存在的所有内容。该行只是在文档的ready事件上注册了一个事件处理程序
回答by ikuegelgen
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);
});
回答by Bear Bear
short answer insert this to bootstrap min.js
简短回答将此插入到 bootstrap min.js
when popout onblur will hide popover
when popout more than one, older popover will be hide
当 popout onblur 将隐藏
popover 当 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;});
回答by Laurens D'Hondt
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. I have written the solution from scratch to be simple and effective.
上述解决方案都没有 100% 对我有用,因为我必须在另一个或相同的弹出窗口上单击两次才能再次打开它。为了简单有效,我从头开始编写了解决方案。
$('[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');
}
});
回答by Mauro Salgado
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');
}
});

