Superposición de modales múltiples

185

Necesito que la superposición se muestre arriba del primer modal, no en la parte posterior.

Superposición modal detrás

Traté de cambiar el z-indexde .modal-backdrop, pero se convierte en un desastre.

En algunos casos tengo más de dos modales en la misma página.

Willian Bonho Daiprai
fuente

Respuestas:

430

Después de ver muchas soluciones para esto, y ninguna de ellas era exactamente lo que necesitaba, se me ocurrió una solución aún más corta inspirada en @YermoLamers y @Ketwaroo.

Corrección del índice z de fondo
Esta solución utiliza un setTimeoutporque .modal-backdropno se crea cuando show.bs.modalse desencadena el evento .

$(document).on('show.bs.modal', '.modal', function () {
    var zIndex = 1040 + (10 * $('.modal:visible').length);
    $(this).css('z-index', zIndex);
    setTimeout(function() {
        $('.modal-backdrop').not('.modal-stack').css('z-index', zIndex - 1).addClass('modal-stack');
    }, 0);
});
  • Esto funciona para cada .modalcreado en la página (incluso modales dinámicos)
  • El fondo se superpone instantáneamente al modal anterior

Ejemplo jsfiddle

Si por algún motivo no le gusta el índice z codificado, puede calcular el índice z más alto en la página de esta manera:

var zIndex = Math.max.apply(null, Array.prototype.map.call(document.querySelectorAll('*'), function(el) {
  return +el.style.zIndex;
})) + 10;

Corrección de la barra de desplazamiento
Si tiene un modal en su página que excede la altura del navegador, entonces no puede desplazarse al cerrar un segundo modal. Para arreglar esto agregue:

$(document).on('hidden.bs.modal', '.modal', function () {
    $('.modal:visible').length && $(document.body).addClass('modal-open');
});

Versiones
Esta solución se prueba con bootstrap 3.1.0 - 3.3.5

A1rPun
fuente
1
@ A1rPun no funciona para mí ... cuando cierro el segundo modal ... el cuerpo se desplaza ... utilicé todo su código ... :(
Vishal
No funcionó en mi entorno con las últimas bs. Tuve que hacer: $ ('. Modal-backdrop'). Last (). Not ('. Modal-stack'). Css ('z-index', zIndex - 1) .addClass ('modal-stack') ;
metamagikum
2
Tuve que hacer un cambio menor (agregado .not(this)a la segunda línea) para que funcionara con bootstrap datepicker var zIndex = 1040 + (10 * $('.modal:visible').not(this).length);
benrwb
Si existen dos modales, entonces el primero se elimina y se agrega un tercero, el tercero tendrá el mismo índice z que el segundo, ya que ambos usaron una longitud de 2. Necesitaba tener en cuenta el último índice z utilizado en todo el modales.
Murphybro2
3
Funciona bien con BS4 más reciente
wobsoriano
85

Me doy cuenta de que se ha aceptado una respuesta, pero sugiero no hackear bootstrap para solucionar esto.

Puede lograr fácilmente el mismo efecto conectando los controladores de eventos shown.bs.modal y hidden.bs.modal y ajustando el índice z allí.

Aquí hay un ejemplo de trabajo

Un poco más de información está disponible aquí.

Esta solución funciona automáticamente con pilas de moda arbitrariamente profundas.

El código fuente del script:

$(document).ready(function() {

    $('.modal').on('hidden.bs.modal', function(event) {
        $(this).removeClass( 'fv-modal-stack' );
        $('body').data( 'fv_open_modals', $('body').data( 'fv_open_modals' ) - 1 );
    });

    $('.modal').on('shown.bs.modal', function (event) {
        // keep track of the number of open modals
        if ( typeof( $('body').data( 'fv_open_modals' ) ) == 'undefined' ) {
            $('body').data( 'fv_open_modals', 0 );
        }

        // if the z-index of this modal has been set, ignore.
        if ($(this).hasClass('fv-modal-stack')) {
            return;
        }

        $(this).addClass('fv-modal-stack');
        $('body').data('fv_open_modals', $('body').data('fv_open_modals' ) + 1 );
        $(this).css('z-index', 1040 + (10 * $('body').data('fv_open_modals' )));
        $('.modal-backdrop').not('.fv-modal-stack').css('z-index', 1039 + (10 * $('body').data('fv_open_modals')));
        $('.modal-backdrop').not('fv-modal-stack').addClass('fv-modal-stack'); 

    });        
});
Yermo Lamers
fuente
3
Genial, sin embargo, cuando un modal está cerrado, aparecen dos barras de desplazamiento: una para modal y la segunda para toda la página. ¿Se puede resolver esto?
Somnium
¿Estás utilizando el último bootstrap?
Yermo Lamers
3
Para lidiar con la barra de desplazamiento adicional al cerrar, debe agregar la clase "modal-open" al cuerpo en el oyente hidden.bs.modal.
Lee
55
Un problema con el que me topé fue cuando aparecía el primer modal y necesitaba una barra de desplazamiento, si mostraba un segundo modal, eliminaría la barra de desplazamiento del primer modal y me quedé atascado con un modal recortado. Para resolver esto, acabo de agregar esto a mi CSS, .modal {overflow-y: auto; }
ScubaSteve
2
Siento que esta debería ser la respuesta aceptada. Funciona perfectamente para mí.
Matthew Goheen el
24

Algo más corto basado en la sugerencia de Yermo Lamers, esto parece funcionar bien. Incluso con animaciones básicas como fundido de entrada / salida e incluso el loco periódico de Batman gira. http://jsfiddle.net/ketwaroo/mXy3E/

$('.modal').on('show.bs.modal', function(event) {
    var idx = $('.modal:visible').length;
    $(this).css('z-index', 1040 + (10 * idx));
});
$('.modal').on('shown.bs.modal', function(event) {
    var idx = ($('.modal:visible').length) -1; // raise backdrop after animation.
    $('.modal-backdrop').not('.stacked').css('z-index', 1039 + (10 * idx));
    $('.modal-backdrop').not('.stacked').addClass('stacked');
});
Ketwaroo D. Yaasir
fuente
77
Un problema que permanece aquí es que si cierra el segundo modal y su página tiene suficiente texto para exceder el tamaño del navegador, terminará con un comportamiento extraño en la barra de desplazamiento. También debe restaurar la modal-openclase en el elemento del cuerpo: jsfiddle.net/vkyjocyn
StriplingWarrior
22

Combinando la respuesta de A1rPun con la sugerencia de StriplingWarrior, se me ocurrió esto:

$(document).on({
    'show.bs.modal': function () {
        var zIndex = 1040 + (10 * $('.modal:visible').length);
        $(this).css('z-index', zIndex);
        setTimeout(function() {
            $('.modal-backdrop').not('.modal-stack').css('z-index', zIndex - 1).addClass('modal-stack');
        }, 0);
    },
    'hidden.bs.modal': function() {
        if ($('.modal:visible').length > 0) {
            // restore the modal-open class to the body element, so that scrolling works
            // properly after de-stacking a modal.
            setTimeout(function() {
                $(document.body).addClass('modal-open');
            }, 0);
        }
    }
}, '.modal');

Funciona incluso para modales dinámicos agregados después del hecho, y elimina el problema de la segunda barra de desplazamiento. Lo más notable para lo que me pareció útil fue integrar formularios dentro de modales con comentarios de validación de las alertas de Bootbox, ya que usan modales dinámicos y, por lo tanto, requieren que enlace el evento para documentar en lugar de .modal, ya que eso solo lo adjunta a los existentes modales.

Violín aquí.

Siete pecados capitales
fuente
2
¿Puedo sugerir usar el índice z máximo de los modales abiertos para determinar el índice z base en lugar del valor codificado de 1040? stackoverflow.com/a/5680815/2569159
harco gijsbers
12

Creé un complemento Bootstrap que incorpora muchas de las ideas publicadas aquí.

Demostración en Bootply: http://www.bootply.com/cObcYInvpq

Github: https://github.com/jhaygt/bootstrap-multimodal

También aborda el problema con modales sucesivos que hacen que el telón de fondo se vuelva más y más oscuro. Esto asegura que solo un fondo sea visible en un momento dado:

if(modalIndex > 0)
    $('.modal-backdrop').not(':first').addClass('hidden');

El índice z del fondo visible se actualiza en los eventos show.bs.modaly hidden.bs.modal:

$('.modal-backdrop:first').css('z-index', MultiModal.BASE_ZINDEX + (modalIndex * 20));
jhay
fuente
Buena solución Espero que el telón de fondo se oscurezca cuando tienes múltiples modales, pero puedo ver por qué no lo quieres. @AndyBurton ¿Puede decirme cuál es la falta de mi solución?
A1rPun
@ A1rPun al abrir y cerrar el segundo modal, se eliminaron las barras de desplazamiento que permitían desplazarse en el primer modal. IIRC esto parecía ser porque la clase en el cuerpo se eliminó cuando se cerró el segundo modal.
Andy Burton
@AndyBurton Yo también manejo la solución a ese problema.
A1rPun
11

Al resolver el apilamiento de modales se desplaza por la página principal cuando uno está cerrado, descubrí que las versiones más nuevas de Bootstrap (al menos desde la versión 3.0.3) no requieren ningún código adicional para apilar modales.

Puede agregar más de un modal (por supuesto, tener una ID diferente) a su página. El único problema que se encuentra al abrir más de un modal será que al cerrar uno elimine elmodal-open clase para el selector de cuerpo.

Puede usar el siguiente código Javascript para volver a agregar el modal-open:

$('.modal').on('hidden.bs.modal', function (e) {
    if($('.modal').hasClass('in')) {
    $('body').addClass('modal-open');
    }    
});

En el caso de que no necesite el efecto de fondo para el modal apilado, puede configurar data-backdrop="false" .

Versión 3.1.1. arreglado Fijar el fondo modal superpuesto a la barra de desplazamiento del modal , pero la solución anterior también parece funcionar con versiones anteriores.

Bass Jobsen
fuente
8

Finalmente resuelto. Lo probé de muchas maneras y funciona bien.

Aquí está la solución para cualquiera que tenga el mismo problema: Cambie la función Modal.prototype.show (en bootstrap.js o modal.js)

DE:

if (transition) {
   that.$element[0].offsetWidth // force reflow
}   

that.$element
   .addClass('in')
   .attr('aria-hidden', false)

that.enforceFocus()

A:

if (transition) {
    that.$element[0].offsetWidth // force reflow
}

that.$backdrop
   .css("z-index", (1030 + (10 * $(".modal.fade.in").length)))

that.$element
   .css("z-index", (1040 + (10 * $(".modal.fade.in").length)))
   .addClass('in')
   .attr('aria-hidden', false)

that.enforceFocus()

Es la mejor manera que encontré: compruebe cuántos modales se abren y cambie el índice z del modal y el fondo a un valor más alto.

Willian Bonho Daiprai
fuente
6

Si está buscando la solución Bootstrap 4, hay una fácil usando CSS puro:

.modal.fade {
    background: rgba(0,0,0,0.5);
}
michal.jakubeczy
fuente
Esto parece funcionar bien ... ¿crees que esto sería Bootstrap estándar?
Ben en California
3

Intente agregar lo siguiente a su JS en bootply

$('#myModal2').on('show.bs.modal', function () {  
$('#myModal').css('z-index', 1030); })

$('#myModal2').on('hidden.bs.modal', function () {  
$('#myModal').css('z-index', 1040); })

Explicación:

Después de jugar con los atributos (usando la herramienta de desarrollo de Chrome), me di cuenta de que cualquier z-indexvalor a continuación 1031pondrá las cosas detrás del telón de fondo.

Entonces, al usar los controladores de eventos modales de bootstrap, configuro el z-indexa 1030. Si #myModal2se muestra y establece la parte z-indexposterior en 1040si #myModal2está oculto.

Manifestación

Madera
fuente
2

Cada vez que ejecuta la función sys.showModal, incremente el índice z y configúrelo en su nuevo modal.

function system() {

    this.modalIndex = 2000;

    this.showModal = function (selector) {
        this.modalIndex++;

        $(selector).modal({
            backdrop: 'static',
            keyboard: true
        });
        $(selector).modal('show');
        $(selector).css('z-index', this.modalIndex );       
    }

}

var sys = new system();

sys.showModal('#myModal1');
sys.showModal('#myModal2');
nuEn
fuente
2

La solución a esto para mí fue NO usar la clase "fade" en mis divs modales.

Tony Schwartz
fuente
2

Sin soluciones de script, usando solo css dado que tiene dos capas de modales, establezca el segundo modal en un índice z más alto

.second-modal { z-index: 1070 }

div.modal-backdrop + div.modal-backdrop {
   z-index: 1060; 
}
Liran Barniv
fuente
2

Si desea que aparezca un modal específico encima de otro modal abierto, intente agregar el HTML del modal superior después del otro modal div.

Esto funcionó para mí:

<div id="modal-under" class="modal fade" ... />

<!--
This modal-upper should appear on top of #modal-under when both are open.
Place its HTML after #modal-under. -->
<div id="modal-upper" class="modal fade" ... />
reformado
fuente
2

Mi solución para bootstrap 4, trabajando con una profundidad ilimitada de modales y modal dinámico.

$('.modal').on('show.bs.modal', function () {
    var $modal = $(this);
    var baseZIndex = 1050;
    var modalZIndex = baseZIndex + ($('.modal.show').length * 20);
    var backdropZIndex = modalZIndex - 10;
    $modal.css('z-index', modalZIndex).css('overflow', 'auto');
    $('.modal-backdrop.show:last').css('z-index', backdropZIndex);
});
$('.modal').on('shown.bs.modal', function () {
    var baseBackdropZIndex = 1040;
    $('.modal-backdrop.show').each(function (i) {
        $(this).css('z-index', baseBackdropZIndex + (i * 20));
    });
});
$('.modal').on('hide.bs.modal', function () {
    var $modal = $(this);
    $modal.css('z-index', '');
});
dexcell
fuente
Funcionó perfectamente para mí
Capitán Ardilla
1

Cada modal debe tener una identificación diferente y cada enlace debe estar dirigido a una identificación modal diferente. Entonces debería ser algo así:

<a href="#myModal" data-toggle="modal">
...
<div id="myModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"></div>
...
<a href="#myModal2" data-toggle="modal">
...
<div id="myModal2" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"></div>
...
paulalexandru
fuente
1

EDITAR: Bootstrap 3.3.4 ha resuelto este problema (y otros problemas modales), por lo que si puede actualizar su CSS y JS de arranque, esa sería la mejor solución. Si no puede actualizar la solución a continuación, seguirá funcionando y esencialmente hace lo mismo que bootstrap 3.3.4 (recalcular y aplicar relleno).

Como Bass Jobsen señaló, las versiones más nuevas de Bootstrap tienen resuelto el índice z. La clase modal-open y el relleno derecho seguían siendo problemas para mí, pero este script inspirado en la solución de Yermo Lamers lo resuelve. Simplemente colóquelo en su archivo JS y disfrute.

$(document).on('hide.bs.modal', '.modal', function (event) {
    var padding_right = 0;
    $.each($('.modal'), function(){
        if($(this).hasClass('in') && $(this).modal().data('bs.modal').scrollbarWidth > padding_right) {
            padding_right = $(this).modal().data('bs.modal').scrollbarWidth
        }
    });
    $('body').data('padding_right', padding_right + 'px');
});

$(document).on('hidden.bs.modal', '.modal', function (event) {
    $('body').data('open_modals', $('body').data('open_modals') - 1);
    if($('body').data('open_modals') > 0) {
        $('body').addClass('modal-open');
        $('body').css('padding-right', $('body').data('padding_right'));
    }
});

$(document).on('shown.bs.modal', '.modal', function (event) {
    if (typeof($('body').data('open_modals')) == 'undefined') {
        $('body').data('open_modals', 0);
    }
    $('body').data('open_modals', $('body').data('open_modals') + 1);
    $('body').css('padding-right', (parseInt($('body').css('padding-right')) / $('body').data('open_modals') + 'px'));
});
puntocomly
fuente
1

¡Mira esto! Esta solución resolvió el problema para mí, algunas líneas simples de CSS:

.modal:nth-of-type(even) {
z-index: 1042 !important;
}
.modal-backdrop.in:nth-of-type(even) {
    z-index: 1041 !important;
}

Aquí hay un enlace a donde lo encontré: Bootply Solo asegúrese de que el .modual que necesita aparecer en la parte superior sea el segundo en el código HTML, para que CSS pueda encontrarlo como "par".

Guntar
fuente
1

trabajar para abrir / cerrar multi modales

jQuery(function()
{
    jQuery(document).on('show.bs.modal', '.modal', function()
    {
        var maxZ = parseInt(jQuery('.modal-backdrop').css('z-index')) || 1040;

        jQuery('.modal:visible').each(function()
        {
            maxZ = Math.max(parseInt(jQuery(this).css('z-index')), maxZ);
        });

        jQuery('.modal-backdrop').css('z-index', maxZ);
        jQuery(this).css("z-index", maxZ + 1);
        jQuery('.modal-dialog', this).css("z-index", maxZ + 2);
    });

    jQuery(document).on('hidden.bs.modal', '.modal', function () 
    {
        if (jQuery('.modal:visible').length)
        {
            jQuery(document.body).addClass('modal-open');

           var maxZ = 1040;

           jQuery('.modal:visible').each(function()
           {
               maxZ = Math.max(parseInt(jQuery(this).css('z-index')), maxZ);
           });

           jQuery('.modal-backdrop').css('z-index', maxZ-1);
       }
    });
});

Manifestación

https://www.bootply.com/cObcYInvpq#

Ivan
fuente
1

Para mí, estas simples reglas de scss funcionaron perfectamente:

.modal.show{
  z-index: 1041;
  ~ .modal.show{
    z-index: 1043;
  }
}
.modal-backdrop.show {
  z-index: 1040;
  + .modal-backdrop.show{
    z-index: 1042;
  }
}

Si estas reglas hacen que el modal incorrecto esté en la parte superior de su caso, cambie el orden de sus divisiones modales o cambie (impar) a (par) en el scss anterior.

Joery
fuente
0

Aquí hay algunos CSS que usan nth-of-typeselectores que parecen funcionar:

.modal:nth-of-type(even) {
    z-index: 1042 !important;
}
.modal-backdrop.in:nth-of-type(even) {
    z-index: 1041 !important;
}

Bootply: http://bootply.com/86973

Zim
fuente
1
Ok, eso es genial, pero puse un tercer modal y no funciona. Tengo algunos scripts que lo generan (como alertas, cuadros de búsqueda, etc.) y puedo tener 3 modales abiertos a la vez (hasta que lo sepa). No soy bueno con CSS, perdón si pierdo algo. Existe el código: bootply.com/86975
Willian Bonho Daiprai
0

Tuve un escenario similar, y después de un poco de I + D encontré una solución. Aunque no soy bueno en JS, aun así he logrado escribir una pequeña consulta.

http://jsfiddle.net/Sherbrow/ThLYb/

<div class="ingredient-item" data-toggle="modal" data-target="#myModal">test1 <p>trerefefef</p></div>
<div class="ingredient-item" data-toggle="modal" data-target="#myModal">tst2 <p>Lorem IpsumLorem IpsumLorem IpsumLorem IpsumLorem IpsumLorem IpsumLorem IpsumLorem IpsumLorem IpsumLorem IpsumLorem IpsumLorem IpsumLorem IpsumLorem IpsumLorem IpsumLorem IpsumLorem IpsumLorem IpsumLorem IpsumLorem IpsumLorem IpsumLorem IpsumLorem IpsumLorem IpsumLorem IpsumLorem IpsumLorem IpsumLorem IpsumLorem IpsumLorem IpsumLorem IpsumLorem IpsumLorem IpsumLorem IpsumLorem IpsumLorem IpsumLorem IpsumLorem IpsumLorem IpsumLorem IpsumLorem IpsumLorem IpsumLorem IpsumLorem Ipsum</p></div>
<div class="ingredient-item" data-toggle="modal" data-target="#myModal">test3 <p>afsasfafafsa</p></div>

<!-- Modal -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
        <h4 class="modal-title" id="myModalLabel">Modal title</h4>
      </div>
      <div class="modal-body">
        ...
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
        <button type="button" class="btn btn-primary">Save changes</button>
      </div>
    </div>
  </div>
</div>





$('.ingredient-item').on('click', function(e){

   e.preventDefault();

    var content = $(this).find('p').text();

    $('.modal-body').html(content);

});
usuario3500842
fuente
0

Agregar variable global en modal.js

var modalBGIndex = 1040; // modal backdrop background
var modalConIndex = 1042; // modal container data 

// show function inside add variable - Modal.prototype.backdrop

var e    = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })

modalConIndex = modalConIndex + 2; // add this line inside "Modal.prototype.show"

that.$element
    .show()
    .scrollTop(0)
that.$element.css('z-index',modalConIndex) // add this line after show modal 

if (this.isShown && this.options.backdrop) {
      var doAnimate = $.support.transition && animate

      modalBGIndex = modalBGIndex + 2; // add this line increase modal background index 2+

this.$backdrop.addClass('in')
this.$backdrop.css('z-index',modalBGIndex) // add this line after backdrop addclass
Arpit Pithadia
fuente
0

Las otras soluciones no funcionaron para mí fuera de la caja. Creo que quizás porque estoy usando una versión más reciente de Bootstrap (3.3.2) ... la superposición aparecía en la parte superior del diálogo modal.

Reformé un poco el código y comenté la parte que estaba ajustando el fondo modal. Esto solucionó el problema.

    var $body = $('body');
    var OPEN_MODALS_COUNT = 'fv_open_modals';
    var Z_ADJUSTED = 'fv-modal-stack';
    var defaultBootstrapModalZindex = 1040;

    // keep track of the number of open modals                   
    if ($body.data(OPEN_MODALS_COUNT) === undefined) {
        $body.data(OPEN_MODALS_COUNT, 0);
    }

    $body.on('show.bs.modal', '.modal', function (event)
    {
        if (!$(this).hasClass(Z_ADJUSTED))  // only if z-index not already set
        {
            // Increment count & mark as being adjusted
            $body.data(OPEN_MODALS_COUNT, $body.data(OPEN_MODALS_COUNT) + 1);
            $(this).addClass(Z_ADJUSTED);

            // Set Z-Index
            $(this).css('z-index', defaultBootstrapModalZindex + (1 * $body.data(OPEN_MODALS_COUNT)));

            //// BackDrop z-index   (Doesn't seem to be necessary with Bootstrap 3.3.2 ...)
            //$('.modal-backdrop').not( '.' + Z_ADJUSTED )
            //        .css('z-index', 1039 + (10 * $body.data(OPEN_MODALS_COUNT)))
            //        .addClass(Z_ADJUSTED);
        }
    });
    $body.on('hidden.bs.modal', '.modal', function (event)
    {
        // Decrement count & remove adjusted class
        $body.data(OPEN_MODALS_COUNT, $body.data(OPEN_MODALS_COUNT) - 1);
        $(this).removeClass(Z_ADJUSTED);
        // Fix issue with scrollbar being shown when any modal is hidden
        if($body.data(OPEN_MODALS_COUNT) > 0)
            $body.addClass('modal-open');
    });

Como nota al margen, si desea usar esto en AngularJs, simplemente coloque el código dentro del método .run () de su módulo.

ClearCloud8
fuente
0

Desafortunadamente, no tengo la reputación de comentar, pero debe tenerse en cuenta que la solución aceptada con la línea de base codificada de un índice z 1040 parece ser superior al cálculo de zIndex que intenta encontrar el zIndex máximo que se representa en la página.

Parece que ciertas extensiones / complementos se basan en contenido DOM de nivel superior, lo que hace que el cálculo de .Max sea un número tan obscenamente grande que no puede aumentar el zIndex más. Esto da como resultado un modal donde la superposición aparece sobre el modal incorrectamente (si usa las herramientas Firebug / Google Inspector, verá un zIndex del orden de 2 ^ n - 1)

No he podido aislar cuál es la razón específica por la cual las diversas formas de Math.Max ​​for z-Index conducen a este escenario, pero puede suceder y parecerá exclusivo para algunos usuarios. (Mis pruebas generales en browserstack tenían este código funcionando perfectamente).

Espero que esto ayude a alguien.

Vincent Cortés
fuente
0

En mi caso, el problema fue causado por una extensión del navegador que incluye los archivos bootstrap.js donde el evento show se manejó dos veces y dos modal-backdrop se agregaron divs, pero al cerrar el modal solo se elimina uno de ellos.

Descubrí que al agregar un punto de interrupción de modificación de subárbol al elemento del cuerpo en Chrome, y seguí agregando los modal-backdropdivs.

Amer Sawan
fuente
0
$(window).scroll(function(){
    if($('.modal.in').length && !$('body').hasClass('modal-open'))
    {
              $('body').addClass('modal-open');
    }

});
stara_wiedzma
fuente
Las respuestas de solo código a menudo no ayudan a señalar por qué ocurrió el problema. Debe incluir una explicación de por qué resuelve el problema. Por favor lea ¿Cómo escribo una buena respuesta?
FluffyKitten
0

Actualización: 22.01.2019, 13.41 Optimicé la solución mediante jhay, que también admite cerrar y abrir diálogos iguales o diferentes cuando, por ejemplo, paso de un detalle a otro hacia adelante o hacia atrás.

(function ($, window) {
'use strict';

var MultiModal = function (element) {
    this.$element = $(element);
    this.modalIndex = 0;
};

MultiModal.BASE_ZINDEX = 1040;

/* Max index number. When reached just collate the zIndexes */
MultiModal.MAX_INDEX = 5;

MultiModal.prototype.show = function (target) {
    var that = this;
    var $target = $(target);

    // Bootstrap triggers the show event at the beginning of the show function and before
    // the modal backdrop element has been created. The timeout here allows the modal
    // show function to complete, after which the modal backdrop will have been created
    // and appended to the DOM.

    // we only want one backdrop; hide any extras
    setTimeout(function () {
        /* Count the number of triggered modal dialogs */
        that.modalIndex++;

        if (that.modalIndex >= MultiModal.MAX_INDEX) {
            /* Collate the zIndexes of every open modal dialog according to its order */
            that.collateZIndex();
        }

        /* Modify the zIndex */
        $target.css('z-index', MultiModal.BASE_ZINDEX + (that.modalIndex * 20) + 10);

        /* we only want one backdrop; hide any extras */
        if (that.modalIndex > 1) 
            $('.modal-backdrop').not(':first').addClass('hidden');

        that.adjustBackdrop();
    });

};

MultiModal.prototype.hidden = function (target) {
    this.modalIndex--;
    this.adjustBackdrop();

    if ($('.modal.in').length === 1) {

        /* Reset the index to 1 when only one modal dialog is open */
        this.modalIndex = 1;
        $('.modal.in').css('z-index', MultiModal.BASE_ZINDEX + 10);
        var $modalBackdrop = $('.modal-backdrop:first');
        $modalBackdrop.removeClass('hidden');
        $modalBackdrop.css('z-index', MultiModal.BASE_ZINDEX);

    }
};

MultiModal.prototype.adjustBackdrop = function () {        
    $('.modal-backdrop:first').css('z-index', MultiModal.BASE_ZINDEX + (this.modalIndex * 20));
};

MultiModal.prototype.collateZIndex = function () {

    var index = 1;
    var $modals = $('.modal.in').toArray();


    $modals.sort(function(x, y) 
    {
        return (Number(x.style.zIndex) - Number(y.style.zIndex));
    });     

    for (i = 0; i < $modals.length; i++)
    {
        $($modals[i]).css('z-index', MultiModal.BASE_ZINDEX + (index * 20) + 10);
        index++;
    };

    this.modalIndex = index;
    this.adjustBackdrop();

};

function Plugin(method, target) {
    return this.each(function () {
        var $this = $(this);
        var data = $this.data('multi-modal-plugin');

        if (!data)
            $this.data('multi-modal-plugin', (data = new MultiModal(this)));

        if (method)
            data[method](target);
    });
}

$.fn.multiModal = Plugin;
$.fn.multiModal.Constructor = MultiModal;

$(document).on('show.bs.modal', function (e) {
    $(document).multiModal('show', e.target);
});

$(document).on('hidden.bs.modal', function (e) {
    $(document).multiModal('hidden', e.target);
});}(jQuery, window));
Synthie
fuente
0

Verifique el recuento de modales y agregue el valor al fondo como índice z

    var zIndex = 1500 + ($('.modal').length*2) + 1;
    this.popsr.css({'z-index': zIndex});

    this.popsr.on('shown.bs.modal', function () {
        $(this).next('.modal-backdrop').css('z-index', zIndex - 1);
    });

    this.popsr.modal('show');
Alper AKPINAR
fuente