Superposition de plusieurs modaux


185

J'ai besoin que la superposition s'affiche au-dessus du premier modal, pas à l'arrière.

Superposition modale derrière

J'ai essayé de changer le z-indexde .modal-backdrop, mais cela devient un désordre.

Dans certains cas, j'ai plus de deux modaux sur la même page.

Réponses:


430

Après avoir vu de nombreux correctifs pour cela, et aucun d'entre eux n'était exactement ce dont j'avais besoin, j'ai trouvé une solution encore plus courte inspirée de @YermoLamers & @Ketwaroo.

Correction du z-index de Backdrop
Cette solution utilise un setTimeoutcar le .modal-backdropn'est pas créé lorsque l'événement show.bs.modalest déclenché.

$(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);
});
  • Cela fonctionne pour chaque .modalcréé sur la page (même les modaux dynamiques)
  • Le fond recouvre instantanément le modal précédent

Exemple jsfiddle

Si vous n'aimez pas le z-index codé en dur pour une raison quelconque, vous pouvez calculer le z-index le plus élevé de la page comme ceci:

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

Correction de la barre de défilement
Si vous avez un modal sur votre page qui dépasse la hauteur du navigateur, vous ne pouvez pas le faire défiler lors de la fermeture d'un deuxième modal. Pour résoudre ce problème, ajoutez:

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

Versions
Cette solution est testée avec bootstrap 3.1.0 - 3.3.5


1
@ A1rPun ne fonctionne pas pour moi .. quand je ferme le deuxième modal .. le corps devient scrollable .. j'ai utilisé tout votre code .. :(
Vishal

Ne fonctionne pas dans mon environnement avec les derniers bs. J'ai dû faire: $ ('. Modal-backdrop'). Last (). Not ('. Modal-stack'). Css ('z-index', zIndex - 1) .addClass ('modal-stack') ;
metamagikum

2
J'ai dû faire un changement mineur (ajouté .not(this)à la deuxième ligne) pour le faire fonctionner avec bootstrap datepicker var zIndex = 1040 + (10 * $('.modal:visible').not(this).length);
benrwb

Si deux modaux existent, alors le premier est supprimé et un troisième est ajouté, le troisième aura le même z-index que le second car ils utilisaient tous deux une longueur de 2. J'avais besoin de prendre en compte le dernier z-index utilisé à travers le modaux.
Murphybro2

3
Fonctionne bien avec la dernière BS4
wobsoriano le

85

Je me rends compte qu'une réponse a été acceptée, mais je suggère fortement de ne pas pirater bootstrap pour résoudre ce problème.

Vous pouvez facilement obtenir le même effet en accrochant les gestionnaires d'événements shown.bs.modal et hidden.bs.modal et en y ajustant le z-index.

Voici un exemple de travail

Un peu plus d'informations sont disponibles ici.

Cette solution fonctionne automatiquement avec des modaux empilés arbitrairement profondément.

Le code source du 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'); 

    });        
});

3
Cool, cependant quand un modal est fermé, il apparaît deux barres de défilement - une pour le modal, la seconde pour la page entière. Cela peut-il être résolu?
Somnium

Utilisez-vous le dernier bootstrap?
Yermo Lamers

3
Pour gérer la barre de défilement supplémentaire à la fermeture, vous devez ajouter la classe "modal-open" au corps de l'écouteur hidden.bs.modal.
Lee

5
Un problème que j'ai rencontré était lorsque le premier modal était affiché et avait besoin d'une barre de défilement, si je montrais un deuxième modal, cela supprimerait la barre de défilement du premier modal et j'étais coincé avec un modal découpé. Pour résoudre ce problème, je viens d'ajouter ceci à mon CSS, .modal {overflow-y: auto; }
ScubaSteve

2
Je pense que cela devrait être la réponse acceptée. Fonctionne parfaitement pour moi.
Matthew Goheen

24

Une version plus courte basée sur la suggestion de Yermo Lamers, cela semble bien fonctionner. Même avec des animations de base comme un fondu entrant / sortant et même une rotation folle du journal batman. 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');
});

7
Un problème qui reste ici est que si vous fermez le deuxième modal et que votre page contient suffisamment de texte pour dépasser la taille du navigateur, vous vous retrouvez avec un comportement de barre de défilement étrange. Vous devez également restaurer la modal-openclasse sur l'élément body: jsfiddle.net/vkyjocyn
StriplingWarrior

22

En combinant la réponse d'A1rPun avec la suggestion de StriplingWarrior, j'ai trouvé ceci:

$(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');

Fonctionne même pour les modaux dynamiques ajoutés après coup et supprime le problème de la deuxième barre de défilement. La chose la plus notable pour laquelle j'ai trouvé cela utile était l'intégration de formulaires dans des modaux avec des commentaires de validation des alertes Bootbox, car ceux-ci utilisent des modaux dynamiques et vous obligent donc à lier l'événement à un document plutôt qu'à un .modal, car cela ne l'attache qu'à l'existant. modaux.

Violon ici.


2
Puis-je suggérer d'utiliser l'indice z max des modaux ouverts pour déterminer le z-index de base au lieu de la valeur codée en dur de 1040? stackoverflow.com/a/5680815/2569159
harco gijsbers

12

J'ai créé un plugin Bootstrap qui intègre beaucoup d'idées publiées ici.

Démo sur Bootply: http://www.bootply.com/cObcYInvpq

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

Il résout également le problème avec les modaux successifs qui font que la toile de fond devient de plus en plus sombre. Cela garantit qu'une seule toile de fond est visible à un moment donné:

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

Le z-index du fond visible est mis à jour sur les événements show.bs.modalet hidden.bs.modal:

$('.modal-backdrop:first').css('z-index', MultiModal.BASE_ZINDEX + (modalIndex * 20));

Belle solution. Je m'attends à ce que la toile de fond s'assombrisse lorsque vous avez plusieurs modaux, mais je peux voir pourquoi vous ne le voudriez pas. @AndyBurton Pouvez-vous s'il vous plaît me faire savoir ce que ma solution manque?
A1rPun

@ A1rPun lors de l'ouverture et de la fermeture du 2ème modal, les barres de défilement qui permettaient le défilement dans le 1er modal ont été supprimées. IIRC a semblé être parce que la classe sur le corps a été supprimée lorsque le 2e modal a été fermé.
Andy Burton

@AndyBurton Je gère également la solution à ce problème.
A1rPun

11

Lors de la résolution de Stacking modals, la page principale fait défiler quand on est fermé, j'ai trouvé que les versions plus récentes de Bootstrap (au moins depuis la version 3.0.3) ne nécessitent aucun code supplémentaire pour empiler les modals.

Vous pouvez ajouter plus d'un modal (bien sûr avec un identifiant différent) à votre page. Le seul problème rencontré lors de l'ouverture de plus d'un modal est que la fermeture d'un modal supprime la modal-openclasse du sélecteur de corps.

Vous pouvez utiliser le code Javascript suivant pour rajouter le modal-open:

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

Dans le cas où vous n'avez pas besoin de l'effet de fond pour le modal empilé, vous pouvez définir data-backdrop="false".

Version 3.1.1. fixe toile de fond modale Fix superposant barre de défilement du modal , mais la solution ci - dessus semble également fonctionner avec les versions antérieures.


8

Enfin résolu. Je l'ai testé de nombreuses façons et fonctionne très bien.

Voici la solution pour quiconque a le même problème: Changez la fonction Modal.prototype.show (à bootstrap.js ou modal.js)

DE:

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

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

that.enforceFocus()

À:

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()

C'est le meilleur moyen que j'ai trouvé: vérifiez combien de modaux sont ouverts et changez le z-index du modal et de l'arrière-plan à une valeur plus élevée.


6

Si vous recherchez une solution Bootstrap 4, il existe une solution simple utilisant du CSS pur:

.modal.fade {
    background: rgba(0,0,0,0.5);
}

Cela semble bien fonctionner ... vous penseriez que ce serait Bootstrap standard?
Ben en Californie

3

Essayez d'ajouter ce qui suit à votre JS au démarrage

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

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

Explication:

Après avoir joué avec les attributs (en utilisant l'outil de développement de Chrome), j'ai réalisé que toute z-indexvaleur ci 1031- dessous mettrait les choses en arrière-plan.

Ainsi , en utilisant les poignées d'événements modales de bootstrap je mis le z-indexà 1030. Si #myModal2s'affiche et réglez le z-indexretour sur 1040si #myModal2est masqué.

Démo


2

Chaque fois que vous exécutez la fonction sys.showModal, incrémentez le z-index et définissez-le sur votre nouveau 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');

2

La solution à cela pour moi était de NE PAS utiliser la classe "fade" sur mes divs modales.


2

Aucune solution de script, en utilisant uniquement css étant donné que vous avez deux couches de modaux, définissez le 2ème modal sur un index z plus élevé

.second-modal { z-index: 1070 }

div.modal-backdrop + div.modal-backdrop {
   z-index: 1060; 
}

2

Si vous souhaitez qu'un modal spécifique apparaisse au-dessus d'un autre modal ouvert, essayez d'ajouter le code HTML du modal supérieur après l'autre modal div.

Cela a fonctionné pour moi:

<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" ... />

2

Ma solution pour bootstrap 4, fonctionnant avec une profondeur illimitée de modaux et un modal dynamique.

$('.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', '');
});

A parfaitement fonctionné pour moi
Captain Squirrel

1

Chaque modal doit recevoir un identifiant différent et chaque lien doit être ciblé vers un identifiant modal différent. Donc ça devrait être quelque chose comme ça:

<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>
...

1

EDIT: Bootstrap 3.3.4 a résolu ce problème (et d'autres problèmes modaux) donc si vous pouvez mettre à jour votre bootstrap CSS et JS, ce serait la meilleure solution. Si vous ne pouvez pas mettre à jour la solution ci-dessous fonctionnera toujours et fera essentiellement la même chose que bootstrap 3.3.4 (recalculer et appliquer un remplissage).

Comme Bass Jobsen l'a souligné, les nouvelles versions de Bootstrap ont résolu le z-index. La classe modal-open et le padding-right étaient encore des problèmes pour moi mais ce script inspiré de la solution Yermo Lamers le résout. Déposez-le simplement dans votre fichier JS et profitez-en.

$(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'));
});

1

Regarde ça! Cette solution a résolu le problème pour moi, quelques lignes CSS simples:

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

Voici un lien vers où je l'ai trouvé: Bootply Assurez-vous simplement que le .modual qui doit apparaître sur Top est le deuxième dans le code HTML, afin que CSS puisse le trouver comme "pair".


1

travailler pour ouvrir / fermer les multi modaux

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);
       }
    });
});

Démo

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


1

Pour moi, ces règles scss simples fonctionnaient parfaitement:

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

Si ces règles font que le mauvais modal est en tête dans votre cas, changez l'ordre de vos divs modales, ou changez (impair) en (pair) dans scss ci-dessus.


0

Voici quelques CSS utilisant des nth-of-typesélecteurs qui semblent fonctionner:

.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


1
Ok, c'est super, mais j'ai mis un troisième modal et ça ne marche pas. J'ai quelques scripts qui le génèrent (comme des alertes, des champs de recherche, etc.) et je peux avoir 3 modaux ouverts à la fois (jusqu'à ce que je sache). Je ne suis pas bon avec le CSS, désolé si je perds quelque chose. Il y a le code: bootply.com/86975
Willian Bonho Daiprai

0

J'ai eu un scénario similaire, et après un peu de R&D, j'ai trouvé une solution. Bien que je ne sois pas génial en JS, j'ai quand même réussi à écrire une petite requête.

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);

});

0

Ajouter une variable globale dans modal.js

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

// affiche la fonction à l'intérieur de la variable d'ajout - 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

0

Les autres solutions n'ont pas fonctionné pour moi hors de la boîte. Je pense peut-être parce que j'utilise une version plus récente de Bootstrap (3.3.2) .... la superposition apparaissait au-dessus de la boîte de dialogue modale.

J'ai remanié un peu le code et commenté la partie qui ajustait le fond modal. Cela a résolu le problème.

    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');
    });

En remarque, si vous souhaitez l'utiliser dans AngularJs, mettez simplement le code à l'intérieur de la méthode .run () de votre module.


0

Malheureusement, je n'ai pas la réputation de commenter, mais il convient de noter que la solution acceptée avec la ligne de base codée en dur d'un z-index 1040 semble être supérieure au calcul zIndex qui tente de trouver le zIndex maximum rendu sur la page.

Il semble que certaines extensions / plugins reposent sur un contenu DOM de haut niveau, ce qui fait du calcul .Max un nombre tellement obscène qu'il ne peut plus incrémenter le zIndex. Il en résulte un modal où la superposition apparaît sur le modal de manière incorrecte (si vous utilisez les outils Firebug / Google Inspector, vous verrez un zIndex de l'ordre de 2 ^ n - 1)

Je n'ai pas été en mesure d'isoler la raison spécifique pour laquelle les différentes formes de Math.Max ​​pour z-Index conduisent à ce scénario, mais cela peut arriver, et cela semblera unique à quelques utilisateurs. (Mes tests généraux sur la pile de navigation avaient ce code fonctionnant parfaitement).

J'espère que cela aide quelqu'un.


0

Dans mon cas, le problème a été causé par une extension de navigateur qui inclut les fichiers bootstrap.js où l'événement show géré deux fois et deux modal-backdropdivs sont ajoutés, mais lors de la fermeture du modal, un seul d'entre eux est supprimé.

Trouvé cela en ajoutant un point d'arrêt de modification de sous-arborescence à l'élément body dans chrome, et suivi de l'ajout des modal-backdropdivs.


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

});

Les réponses basées uniquement sur le code sont souvent inutiles pour expliquer pourquoi le problème s'est produit. Vous devez inclure une explication de la raison pour laquelle cela résout le problème. Veuillez lire Comment écrire une bonne réponse?
FluffyKitten

0

Mise à jour: 22.01.2019, 13.41 J'ai optimisé la solution par jhay, qui prend également en charge la fermeture et l'ouverture de boîtes de dialogue identiques ou différentes, par exemple lors du passage d'une donnée de détail à une autre en avant ou en arrière.

(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));

0

Vérifiez le nombre de modaux et ajoutez la valeur à Backdrop en tant que z-index

    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');
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.