javascript - modal - ventana emergente bootstrap 4
Cómo cerrar la ventana emergente Angular-bootstrap al hacer clic fuera (5)
cerrar la ventana emergente al hacer clic en cualquier lugar fuera de la ventana emergente
Hace algún tiempo encontré útil esta respuesta: ¿Cómo descartar una ventana emergente de Twitter Bootstrap haciendo clic afuera?
El código que usé en una de mis demostraciones (mezclar el manejo de eventos angular
y jQuery
que probablemente no se recomienda) es específico para mis necesidades, pero puede dar una idea:
app.directive("eventlistener", function($rootScope) {
$(window).resize($rootScope.closeAllPopovers); // because Bootstrap popovers don''t look good when misplaced
return {
link: function(scope, element, attrs) {
$(''body'').on(''mouseup touchend'', $rootScope.closeAllPopovers);
}
};
});
$rootScope.closeAllPopovers = function (e) {
$(''[data-toggle="popover"]'').each(function () {
if (e) {
if (!$(this).is(e.target) && $(this).has(e.target).length === 0 && $(''.popover'').has(e.target).length === 0) {
$(this).popover(''hide'');
}
} else {
// No event passed - closing all popovers programmatically
$(this).popover(''hide'');
}
});
};
También sugiero mirar la diferencia entre:
Esta pregunta ya tiene una respuesta aquí:
Estoy intentando cerrar las ventanas popover
Angular-bootstrap cuando popover
clic en cualquier lugar fuera de las ventanas emergentes. De acuerdo con la respuesta a esta pregunta, esto se puede lograr ahora (en la versión 0.13.4) utilizando el nuevo atributo popover-is-open
: Ocultar popover UI Bootstrap al hacer clic fuera de ella
Actualmente mi HTML se ve así:
<div
ng-click="level.openTogglePopover()"
popover-template="level.changeLevelTemplate"
popover-trigger="none"
popover-placement="right"
popover-is-open="level.togglePopover">
<button class="btn btn-default btn-xs" type="button">
<span class="glyphicon glyphicon-sort"></span>
</button>
</div>
... y mi código de controlador relevante:
vm.togglePopover = false;
vm.openTogglePopover = function() {
vm.togglePopover = !vm.togglePopover;
};
Esto funciona muy bien para abrir / cerrar la ventana emergente al hacer clic en el botón al que se hace referencia anteriormente. Mi pregunta es, ¿cómo extendería esta funcionalidad para cerrar la ventana emergente al hacer clic en cualquier lugar fuera de la ventana emergente? ¿Cómo puedo configurar mi gestión de eventos para lograr esto?
Desde angular-ui 1.0.0, hay un nuevo desencadenador outsideClick
para información sobre herramientas y outsideClick
(introducido en esta solicitud de extracción :
<div
uib-popover-template="level.changeLevelTemplate"
popover-trigger="outsideClick"
popover-placement="right">
<button class="btn btn-default btn-xs" type="button">
<span class="glyphicon glyphicon-sort"></span>
</button>
</div>
En primer lugar, si desea que la ventana emergente se cierre con cualquier clic, no solo el que está fuera de su ventana emergente, puede hacerlo utilizando el código existente de UI-Bootstrap:
<button class="btn btn-default btn-xs" type="button"
popover-template="level.changeLevelTemplate"
popover-trigger="focus"
popover-placement="right">
<span class="glyphicon glyphicon-sort"></span>
</button>
El truco aquí es dejar caer el <div>
rodea y colocar el popover-trigger="focus"
justo en el botón.
Si realmente necesita cerrar la ventana emergente solo para clics fuera del contenido de la ventana emergente, entonces será más difícil. Necesitas una nueva directiva, como esta:
app.directive(''clickOutside'', function ($parse, $timeout) {
return {
link: function (scope, element, attrs) {
function handler(event) {
if(!$(event.target).closest(element).length) {
scope.$apply(function () {
$parse(attrs.clickOutside)(scope);
});
}
}
$timeout(function () {
// Timeout is to prevent the click handler from immediately
// firing upon opening the popover.
$(document).on("click", handler);
});
scope.$on("$destroy", function () {
$(document).off("click", handler);
});
}
}
});
Luego, en su plantilla emergente, use la directiva en el elemento más externo:
<div click-outside="level.closePopover()">
... (actual popover content goes here)
</div>
Finalmente, en su controlador, implemente la función closePopover
:
vm.closePopover = function () {
vm.togglePopover = false;
};
Lo que hemos hecho aquí es:
- estamos escuchando los clics en el documento y, si el clic está fuera del elemento al que agregamos nuestra directiva de
close-popover
:- Invocamos cualquier código que fuera el valor de
close-popover
- Invocamos cualquier código que fuera el valor de
- también limpiamos después de nosotros mismos cuando se destruye el alcance de la directiva (es decir, cuando se cierra la ventana emergente) para que no manejemos más los clics.
No es la solución más limpia, ya que tiene que invocar el método del controlador desde la plantilla emergente, pero es la mejor que se me ocurrió.
Necesitará realizar el manejo del evento usted mismo, ya que cuando utiliza los nuevos atributos *-is-open
, no hay manejo del evento.
Si no necesita el control programático para abrir / cerrar la ventana emergente, puede usar el disparador de focus
incorporado para darle lo que desea.
Si entendí correctamente, desea que la ventana emergente se cierre cuando un usuario haga clic en casi cualquier lugar, excepto en el interior de la ventana emergente, salvo el botón de cierre real. Esto se podría lograr con un oyente de eventos:
$(''html'').click(function() {
if(!$(event.target).is(''#foo'')) {
// Code to hide/remove popovers
}
});
Echa un vistazo a este plunkr .
O, en su escenario específico:
$(''html'').click(function() {
if(!$(event.target).is(''.my-popover-class'')) {
vm.togglePopover = false;
}
})