¿Cómo descartar una ventana emergente de Twitter Bootstrap haciendo clic afuera?
¿Podemos hacer que los popovers sean descartables de la misma manera que los modales, es decir? ¿Hacerlos cerrar cuando el usuario hace clic en algún lugar fuera de ellos?
Desafortunadamente, no puedo usar modal real en lugar de popover, porque modal significa posición: fija y eso ya no sería popover. :(
Actualización: una solución un poco más sólida: http://jsfiddle.net/mattdlockyer/C5GBU/72/
Para botones que contienen solo texto:
$('body').on('click', function (e) {
//did not click a popover toggle or popover
if ($(e.target).data('toggle') !== 'popover'
&& $(e.target).parents('.popover.in').length === 0) {
$('[data-toggle="popover"]').popover('hide');
}
});
Para botones que contienen íconos, use (este código tiene un error en Bootstrap 3.3.6, consulte la solución a continuación en esta respuesta)
$('body').on('click', function (e) {
//did not click a popover toggle, or icon in popover toggle, or popover
if ($(e.target).data('toggle') !== 'popover'
&& $(e.target).parents('[data-toggle="popover"]').length === 0
&& $(e.target).parents('.popover.in').length === 0) {
$('[data-toggle="popover"]').popover('hide');
}
});
Para popovers generados por JS Úselo '[data-original-title]'
en lugar de'[data-toggle="popover"]'
Advertencia: la solución anterior permite abrir varias ventanas emergentes a la vez.
Un popover a la vez, por favor:
Actualización: Bootstrap 3.0.x, consulte el código o toque el violín http://jsfiddle.net/mattdlockyer/C5GBU/2/
$('body').on('click', function (e) {
$('[data-toggle="popover"]').each(function () {
//the 'is' for buttons that trigger popups
//the 'has' for icons within a button that triggers a popup
if (!$(this).is(e.target) && $(this).has(e.target).length === 0 && $('.popover').has(e.target).length === 0) {
$(this).popover('hide');
}
});
});
Esto maneja el cierre de ventanas emergentes que ya están abiertas y en las que no se ha hecho clic o en sus enlaces no se ha hecho clic.
Actualización: Bootstrap 3.3.6, ver violín
Soluciona el problema por el cual, después de cerrar, se necesitan 2 clics para volver a abrir
$(document).on('click', function (e) {
$('[data-toggle="popover"],[data-original-title]').each(function () {
//the 'is' for buttons that trigger popups
//the 'has' for icons within a button that triggers a popup
if (!$(this).is(e.target) && $(this).has(e.target).length === 0 && $('.popover').has(e.target).length === 0) {
(($(this).popover('hide').data('bs.popover')||{}).inState||{}).click = false // fix for BS 3.3.6
}
});
});
Actualización: Utilizando el condicional de la mejora anterior, se logró esta solución. Solucione el problema del doble clic y la ventana emergente fantasma:
$(document).on("shown.bs.popover",'[data-toggle="popover"]', function(){
$(this).attr('someattr','1');
});
$(document).on("hidden.bs.popover",'[data-toggle="popover"]', function(){
$(this).attr('someattr','0');
});
$(document).on('click', function (e) {
$('[data-toggle="popover"],[data-original-title]').each(function () {
//the 'is' for buttons that trigger popups
//the 'has' for icons within a button that triggers a popup
if (!$(this).is(e.target) && $(this).has(e.target).length === 0 && $('.popover').has(e.target).length === 0) {
if($(this).attr('someattr')=="1"){
$(this).popover("toggle");
}
}
});
});
$('html').on('mouseup', function(e) {
if(!$(e.target).closest('.popover').length) {
$('.popover').each(function(){
$(this.previousSibling).popover('hide');
});
}
});
Esto cierra todas las ventanas emergentes si hace clic en cualquier lugar excepto en una ventana emergente.
ACTUALIZACIÓN para Bootstrap 4.1
$("html").on("mouseup", function (e) {
var l = $(e.target);
if (l[0].className.indexOf("popover") == -1) {
$(".popover").each(function () {
$(this).popover("hide");
});
}
});
La versión más simple y a prueba de fallas , funciona con cualquier versión de arranque.
Demostración: http://jsfiddle.net/guya/24mmM/
Demostración 2: No descartar al hacer clic dentro del contenido emergente http://jsfiddle.net/guya/fjZja/
Demostración 3: múltiples ventanas emergentes: http://jsfiddle.net/guya/6YCjW/
Simplemente llamar a esta línea descartará todos los popovers:
$('[data-original-title]').popover('hide');
Descarte todas las ventanas emergentes al hacer clic afuera con este código:
$('html').on('click', function(e) {
if (typeof $(e.target).data('original-title') == 'undefined') {
$('[data-original-title]').popover('hide');
}
});
El fragmento de arriba adjunta un evento de clic en el cuerpo. Cuando el usuario hace clic en una ventana emergente, se comportará normalmente. Cuando el usuario hace clic en algo que no es una ventana emergente, se cerrarán todas las ventanas emergentes.
También funcionará con ventanas emergentes que se inician con Javascript, a diferencia de otros ejemplos que no funcionarán. (ver la demostración)
Si no desea descartar al hacer clic dentro del contenido de la ventana emergente, use este código (consulte el enlace a la segunda demostración):
$('html').on('click', function(e) {
if (typeof $(e.target).data('original-title') == 'undefined' && !$(e.target).parents().is('.popover.in')) {
$('[data-original-title]').popover('hide');
}
});
Ninguna de las supuestas soluciones más votadas funcionó correctamente para mí. Cada uno genera un error cuando después de abrir y cerrar (haciendo clic en otros elementos) la ventana emergente por primera vez, no se abre nuevamente, hasta que haga dos clics en el enlace de activación en lugar de uno.
Así que lo modifiqué ligeramente:
$(document).on('click', function (e) {
var
$popover,
$target = $(e.target);
//do nothing if there was a click on popover content
if ($target.hasClass('popover') || $target.closest('.popover').length) {
return;
}
$('[data-toggle="popover"]').each(function () {
$popover = $(this);
if (!$popover.is(e.target) &&
$popover.has(e.target).length === 0 &&
$('.popover').has(e.target).length === 0)
{
$popover.popover('hide');
} else {
//fixes issue described above
$popover.popover('toggle');
}
});
})
Con bootstrap 2.3.2 puedes configurar el disparador para 'enfocar' y simplemente funciona:
$('#el').popover({trigger:'focus'});