Superposition de plusieurs modèles

j'ai besoin que la superposition montre au-dessus du premier modal, pas dans le dos.

Modal overlay behind

$('#openBtn').click(function(){
	$('#myModal').modal({show:true})
});
<a data-toggle="modal" href="#myModal" class="btn btn-primary">Launch modal</a>

<div class="modal" id="myModal">
	<div class="modal-dialog">
      <div class="modal-content">
        <div class="modal-header">
          <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
          <h4 class="modal-title">Modal title</h4>
        </div><div class="container"></div>
        <div class="modal-body">
          Content for the dialog / modal goes here.
          <br>
          <br>
          <br>
          <br>
          <br>
          <a data-toggle="modal" href="#myModal2" class="btn btn-primary">Launch modal</a>
        </div>
        <div class="modal-footer">
          <a href="#" data-dismiss="modal" class="btn">Close</a>
          <a href="#" class="btn btn-primary">Save changes</a>
        </div>
      </div>
    </div>
</div>
<div class="modal" id="myModal2" data-backdrop="static">
	<div class="modal-dialog">
      <div class="modal-content">
        <div class="modal-header">
          <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
          <h4 class="modal-title">Second Modal title</h4>
        </div><div class="container"></div>
        <div class="modal-body">
          Content for the dialog / modal goes here.
        </div>
        <div class="modal-footer">
          <a href="#" data-dismiss="modal" class="btn">Close</a>
          <a href="#" class="btn btn-primary">Save changes</a>
        </div>
      </div>
    </div>
</div>


<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.0.0/css/bootstrap.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.0.0/js/bootstrap.min.js"></script>

j'ai essayé de changer le z-index de .modal-backdrop , mais il devient un gâchis.

dans certains cas, j'ai plus de deux modèles sur la même page.

150
demandé sur Emile Bergeron 0000-00-00 00:00:00

7 réponses

après avoir vu de nombreux correctifs pour cela, et aucun d'entre eux étaient exactement ce dont j'avais besoin, j'ai trouvé une solution encore plus courte qui est inspiré par @yermolamers & @Ketwaroo.

background z-index fix

Cette solution utilise un setTimeout parce que le .modal-backdrop n'est pas créé lorsque l'événement show.bs.modal est 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 .modal créé sur la page (même les modaux dynamiques)
  • La toile de fond instantanément des superpositions de la précédente modal

exemple jsfiddle

si vous n'aimez pas l'index z codé en dur pour n'importe quelle raison, vous pouvez calculer le plus haut index z sur la page comme ceci:

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

Barre de défilement fix

Si vous avez un modal sur votre page qui dépasse la hauteur du navigateur, alors vous ne pouvez pas le faire défiler lors de la fermeture d'un second modal. Pour corriger cela, ajouter:

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

333
répondu A1rPun 2015-12-04 20:08:51

je me rends compte qu'une réponse a été acceptée, mais je suggère fortement de ne pas hacker bootstrap pour corriger cela.

vous pouvez assez facilement obtenir le même effet en accrochant le montré.bs.modal et caché.bs.modal event handlers and adjusting the z-index there.

voici un exemple pratique

un peu plus d'info est disponible ici.

Cette solution fonctionne automatiquement avec arbitrairement profondément piles auxiliaires modaux.

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

    });        
});
72
répondu Yermo Lamers 2018-02-21 12:46:01

quelque chose de plus court version basée sur la suggestion de Yermo Lamers, cela semble bien fonctionner. Même avec des animations de base comme fade in / out et même crazy batman journal rotation. 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');
});
21
répondu Ketwaroo D. Yaasir 2014-04-15 16:19:51

combinant la réponse D'A1rPun avec la suggestion de StriplingWarrior, je suis venu avec 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 le fait, et supprime la question du second-scrollbar. La chose la plus notable pour laquelle j'ai trouvé cela utile était l'intégration des formulaires à l'intérieur des modaux avec les retours de validation des alertes Bootbox, car ceux-ci utilisent des modaux dynamiques et exigent donc que vous liiez l'événement au document plutôt qu'à .modale, étant donné que seuls les l'attache à l'existant, les auxiliaires modaux.

Violon ici.

18
répondu Seven Deadly Sins 2014-09-22 19:38:43

j'ai créé un plugin Bootstrap qui incorpore beaucoup des idées postées ici.

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

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

Il aborde également la question successifs, les auxiliaires modaux causant la toile de fond pour devenir de plus en plus sombre. Cela garantit qu'une seule toile de fond est visible à tout moment heure:

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

l'index en z de la toile de fond visible est mis à jour sur les deux événements show.bs.modal et hidden.bs.modal :

$('.modal-backdrop:first').css('z-index', MultiModal.BASE_ZINDEX + (modalIndex * 20));
11
répondu jhay 2015-12-10 21:29:03

lors de la résolution de modaux D'empilage scrolls la page principale quand on est fermé j'ai constaté que les nouvelles versions de Bootstrap (au moins depuis la version 3.0.3) ne nécessitent pas de code supplémentaire pour empiler les modaux.

vous pouvez ajouter plus d'un modal (ayant bien sûr un ID différent) à votre page. Le seul problème rencontré lors de l'ouverture de plus d'un modal sera que la fermeture d'un modal supprimera la classe modal-open pour le sélecteur de carrosserie.

vous pouvez utiliser le code Javascript suivant pour re-ajouter le modal-open :

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

dans le cas qui n'ont pas besoin de l'effet de fond pour le modal empilé, vous pouvez définir data-backdrop="false" .

Version 3.1.1. fixe fixe arrière-plan modal superposant le scrollbar modal , mais la solution ci-dessus semble également fonctionner avec les versions précédentes.

9
répondu Bass Jobsen 2017-05-23 12:34:50

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

Voici la solution pour tous ceux qui ont le même problème: Changer le Modal .prototype.afficher la fonction (à bootstrap.js ou modale.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érifier combien les auxiliaires modaux sont ouverts et changer l'indice z du modal et de la toile de fond à une valeur plus élevée.

8
répondu Willian Bonho Daiprai 2013-10-11 15:00:56