javascript - tamaño - Bootstrap Modal Backdrop Restante
modal extra large bootstrap (14)
Estoy mostrando una ventana modal de Bootstrap para cargar cuando realizo llamadas AJAX. Transmití un evento "progress.init" cuando el modal de carga debería mostrarse y un "progress.finish" cuando quiero que el modal se oculte. Existen ciertas condiciones en las que el modal se oculta muy rápidamente después de mostrarse, lo que hace que el fondo modal permanezca en la pantalla. Las llamadas subsiguientes a ocultar el elemento no eliminan el fondo. Tampoco puedo simplemente eliminar todos los telones de fondo ya que otras ventanas modales se pueden mostrar en la ventana de carga. He creado un jsfiddle demuestra el problema simplemente llamando a la función modal (en lugar de desencadenar eventos).
var loadingModal = $("#loadingModal");
$("#btnShow").click(function () {
loadingModal.modal("show");
//hide after 3 seconds
setTimeout(function () {
loadingModal.modal("hide");
}, 3000);
});
$("#btnProblem").click(function () {
//simulate a loading screen finishing fast, followed by another loading screen
loadingModal.modal("show");
loadingModal.modal("hide");
loadingModal.modal("show");
//Again simulate 3 seconds
setTimeout(function () {
loadingModal.modal("hide");
}, 3000);
});
Y el HTML:
<div id="loadingModal" class="modal fade">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
<p>Loading...</p>
</div>
</div>
</div>
</div>
<button id="btnShow">Show Loading</button>
<button id="btnProblem">Cause show/hide problem</button>
Idealmente, me gustaría resolver esto sin esperar un tiempo específico antes de llamar a modal ("ocultar"). En otras palabras, quiero tratar de evitar algo como:
elem.on("progress.finish", function () {
window.setTimeout(loadingModal.modal("hide");
}, 750);
También he intentado suscribirme a los eventos hidden.bs.modal y shown.bs.modal de bootstrap para tratar de mostrar / ocultar el elemento si es necesario, pero puede estar yendo mal ... Cualquier idea para permitir esto modal para mostrar / ocultar?
Agrega esto:
$ (". modal-backdrop"). hide ();
a la función ng-click en el controlador para evitar que se mantenga el fondo de fundido de entrada.
Después de inspeccionar el elemento, el div
con la clase modal-backdrop
aún permanece después de presionar el botón de navegación hacia atrás, así que simplemente lo elimino:
$(window).on(''popstate'', function() {
$(".modal-backdrop").remove();
});
El mejor y más simple enfoque es usar el atributo de data-dismiss
. Básicamente, el atributo de data-dismiss
descartará el modal y no verá el fondo restante.
Cómo usar el atributo de descarte de datos
Todo lo que necesita hacer es agregar lo siguiente en el lugar donde desea cerrar su modal:
data-dismiss="modal"
Por ejemplo, tengo un botón y cuando alguien hace clic en el botón cerrará el modal.
<button class="btn btn-info float-right" onclick="foo()" data-dismiss="modal">Save changes</button>
También puede manejar la función de JavaScript en onClick
y cerrará el modal y también ejecutará la función de JavaScript.
Este es el mejor enfoque para hacer usando el atributo de data-dismiss
.
El problema es que bootstrap elimina el fondo de manera asincrónica. Entonces, cuando llamas a hide
y show
rápidamente uno detrás del otro, el fondo no se elimina.
La solución (como has mencionado) es esperar a que el modal se haya ocultado por completo, usando el evento ''hidden.bs.modal''
. Use jQuery one para realizar solo la devolución de llamada una vez. He bifurcado tu jsfiddle para mostrar cómo funcionaría esto.
// wait for the backdrop to be removed nicely.
loadingModal.one(''hidden.bs.modal'', function()
{
loadingModal.modal("show");
//Again simulate 3 seconds
setTimeout(function () {
loadingModal.modal("hide");
}, 3000);
});
// hide for the first time, after binding to the hidden event.
loadingModal.modal("hide");
Mirando el código en Bootstrap:
Esto es lo que hace que se oculte el modo asincrónico :
$.support.transition && this.$element.hasClass(''fade'') ?
this.$element
.one(''bsTransitionEnd'', $.proxy(this.hideModal, this))
.emulateTransitionEnd(Modal.TRANSITION_DURATION) :
this.hideModal()
Esto comprueba si las transiciones son compatibles y la clase de fade
está incluida en el modal. Cuando ambos son true
, espera a que se complete el efecto de fundido, antes de ocultar el modal. Esta espera vuelve a suceder antes de eliminar el fondo .
Esta es la razón por la que al eliminar la clase de fundido se oculta el modal sincrónico (no hay que esperar a que se complete el efecto de fundido de CSS) y por qué funciona la solución de reznic.
Esta comprobación determina si agregar o eliminar el fondo. isShown = true
se realiza de forma síncrona . Cuando llama a hide
y show
rápidamente uno detrás del otro, isShown
convierte en true
y el cheque agrega un fondo, en lugar de eliminar el anterior, creando el problema que está teniendo.
En caso de que alguien más se encuentre con un problema similar: mantuve el fade, pero simplemente agregué data-dismiss="modal"
al botón de guardar. Funciona para mi.
Esto es lo que funcionó para mí:
Cuando se hidden.bs.modal
evento hidden.bs.modal
, la función .remove()
jQuery
puede eliminar el elemento que tiene la clase .modal-backdrop
. Por lo tanto, cada vez que se cierre el modal , se eliminará el telón modal .
//setting callback function for ''hidden.bs.modal'' event
$(''#modal'').on(''hidden.bs.modal'', function(){
//remove the backdrop
$(''.modal-backdrop'').remove();
})
Buena suerte.
La solución consiste en ocultar el fondo por completo si no necesita uno como este: data-backdrop = ""
<div class="modal fade preview-modal" data-backdrop="" id="preview-modal" role="dialog" aria-labelledby="preview-modal" aria-hidden="true">
Otro posible caso (mío): está agregando modal html dinámicamente a DOM y contiene más el 1 nodo raíz. He aquí que los nodos de comentarios también cuentan, por lo tanto, si copió la plantilla del sitio de arranque, los tiene.
Por lo tanto, si no desea eliminar el fundido o el tinker con los objetos dom, todo lo que tiene que hacer es asegurarse de esperar a que finalice el espectáculo:
$(''#load-modal'').on(''shown.bs.modal'', function () {
console.log(''Shown Modal Backdrop'');
$(''#load-modal'').addClass(''shown'');
});
function HideLoader() {
var loadmodalhidetimer = setInterval(function () {
if ($(''#load-modal'').is(''.shown'')) {
$(''#load-modal'').removeClass(''shown'').modal(''hide'');
clearInterval(loadmodalhidetimer);
console.log(''HideLoader'');
}
else { //this is just for show.
console.log(''Waiting to Hide'');
}
}, 200);
}
IMO Bootstrap ya debería estar haciendo esto. Bueno, tal vez un poco más, si hay una posibilidad de que puedas llamar a hide sin haberlo hecho, tal vez quieras agregar un poco en show.bs.modal, agrega la clase ''showing'' y asegúrate de que el temporizador verifique que se muestre previsto antes de entrar en el ciclo. Asegúrese de borrar ''mostrar'' en el punto en que se muestra.
Sea cuidadoso agregando {data-dismiss = "modal"} como se menciona en la segunda respuesta. Cuando se trabaja con Angular ng-commit utilizando una función definida por alcance de controlador, el descarte de datos se ejecutará primero y nunca se llamará a la función definida por alcance de controlador. Paso una hora para resolver esto.
Si después de la ocultación modal, se mantiene el fondo difuminado y no le permite hacer clic en cualquier lugar donde pueda eliminarlos mediante el uso de la siguiente pieza de código.
primero esconde tu elemento div modal.
$(''modalId'').modal(''hide'');
en segundo lugar, eliminar la clase ''modal-open'' del cuerpo y ''.modal-backdrop'' al final de la página.
$(''body'').removeClass(''modal-open'');
$(''.modal-backdrop'').remove();
Solo en caso de que alguien más se encuentre con un problema similar: descubrí que sacar a la clase "fade" del modal evitará que este fondo se adhiera a la pantalla incluso después de que el modal esté oculto. Parece ser un error en bootstrap.js para los modales.
Otro (mientras se mantienen los efectos de fundido) sería reemplazar la llamada a jQueryElement.modal con su propio javascript personalizado que agrega la clase "in", establece display: block, y agrega un fondo cuando se muestra, luego para realizar las operaciones opuestas cuando quieres ocultar el modal.
Simplemente eliminar el fundido fue suficiente para mi proyecto.
Un problema que estaba teniendo (puede ayudar a alguien) era simplemente que estaba usando un parcial para cargar el Modal.
<li data-toggle="modal" data-target="#priceInfoModal">
<label>Listing Price</label>
<i class="fa fa-money"></i>
@Html.Partial("EditPartials/PriceInfo_Edit")
</li>
Coloqué la llamada parcial dentro del mismo elemento de la lista. Data-target = "# priceInfoModal" y div id = "priceInfoModal" estaban en el mismo contenedor y no pude cerrar mi modal
simplemente elimine la clase ''fade'' del modal