Nakładka z wieloma modami

185

Potrzebuję, aby nakładka pokazywała się nad pierwszym modułem, a nie z tyłu.

Nakładka modalna z tyłu

Starałem się zmienić z-indexod .modal-backdrop, ale staje się bałagan.

W niektórych przypadkach mam więcej niż dwa moduły na tej samej stronie.

Willian Bonho Daiprai
źródło

Odpowiedzi:

430

Po zobaczeniu wielu poprawek do tego, a żadna z nich nie była dokładnie tym, czego potrzebowałem, wpadłem na jeszcze krótsze rozwiązanie, które jest inspirowane przez @YermoLamers & @Ketwaroo.

Tło poprawki z-index
To rozwiązanie wykorzystuje, setTimeoutponieważ .modal-backdropnie jest tworzone, gdy zdarzenie show.bs.modaljest wyzwalane.

$(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);
});
  • Działa to dla każdego .modalutworzonego na stronie (nawet dynamicznego)
  • Tło natychmiast nakłada się na poprzedni modal

Przykład jsfiddle

Jeśli z jakiegoś powodu nie podoba ci się sztywny indeks Z, możesz obliczyć najwyższy indeks Z na stronie w następujący sposób:

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

Poprawka paska przewijania
Jeśli na stronie znajduje się modal, który przekracza wysokość przeglądarki, nie można go przewijać podczas zamykania drugiego modalu. Aby naprawić to dodaj:

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

Wersje
To rozwiązanie jest testowane z bootstrap 3.1.0 - 3.3.5

A1rPun
źródło
1
@ A1rPun nie działa dla mnie .. kiedy zamykam drugi modal ... ciało staje się przewijalne .. użyłem całego twojego kodu .. :(
Vishal
Nie działał w moim środowisku z najnowszym BS. Musiałem zrobić: $ ('. Modal-background'). Last (). Not ('. Modal-stack'). Css ('z-index', zIndex - 1) .addClass ('modal-stack') ;
metamagikum,
2
Musiałem dokonać drobnej zmiany (dodanej .not(this)do drugiej linii), aby działała z var zIndex = 1040 + (10 * $('.modal:visible').not(this).length);
bootplastem
Jeśli istnieją dwa moduły, pierwszy jest usuwany, a trzeci dodawany, trzeci będzie miał taki sam indeks Z jak drugi, ponieważ oba miały długość 2. Musiałem uwzględnić ostatni używany indeks Z w całym moduły.
Murphybro2
3
Działa dobrze z najnowszym BS4
wobsoriano
85

Zdaję sobie sprawę, że odpowiedź została zaakceptowana, ale zdecydowanie sugeruję, aby nie hakować bootstrap, aby to naprawić.

Możesz dość łatwo osiągnąć ten sam efekt, przechwytując moduły obsługi zdarzeń pokazanych na zdjęciu.bs.modal i hidden.bs.modal i dostosowując tam indeks Z.

Oto działający przykład

Trochę więcej informacji jest dostępnych tutaj.

To rozwiązanie działa automatycznie z dowolnie głęboko stosami modów.

Kod źródłowy skryptu:

$(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
źródło
3
Fajnie, jednak gdy jeden modal jest zamknięty, pojawiają się dwa paski przewijania - jeden dla modalu, drugi dla całej strony. Czy można to rozwiązać?
Somnium
Czy używasz najnowszego bootstrapu?
Yermo Lamers
3
Aby poradzić sobie z dodatkowym paskiem scoll po zamknięciu, musisz dodać do ciała klasę „modal-open” w nasłuchu ukrytym.bs.modal.
Lee,
5
Jednym z problemów, na jakie natrafiłem, było wyświetlenie pierwszego modalu i potrzebowałem paska przewijania, gdybym pokazał drugi modal, usunąłby pasek przewijania pierwszego modalu i utknąłem z przyciętym modalem. Aby rozwiązać ten problem, właśnie dodałem to do mojego CSS, .modal {overflow-y: auto; }
ScubaSteve,
2
Wydaje mi się, że to powinna być zaakceptowana odpowiedź. Działa dla mnie bezbłędnie.
Matthew Goheen
24

Coś krótsza wersja oparta na sugestii Yermo Lamersa, wydaje się, że działa dobrze. Nawet z podstawowymi animacjami, takimi jak zanikanie i zanikanie, a nawet szalona gazeta o batmanie się obraca. 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
źródło
7
Jednym z problemów, który pozostaje tutaj, jest to, że jeśli zamkniesz drugi modal, a strona ma wystarczającą ilość tekstu, aby przekroczyć rozmiar przeglądarki, skończy się dziwne zachowanie paska przewijania. Musisz także przywrócić modal-openklasę na elemencie ciała: jsfiddle.net/vkyjocyn
StriplingWarrior
22

Łącząc odpowiedź A1rPun z sugestią StriplingWarrior, wymyśliłem:

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

Działa nawet w przypadku dynamicznych modów dodanych po fakcie i usuwa problem z drugim paskiem przewijania. Najbardziej godną uwagi rzeczą, dla której uznałem to za przydatne, było integrowanie formularzy w modach ze sprzężeniem zwrotnym sprawdzania poprawności z alertów Bootbox, ponieważ używają one modów dynamicznych, a zatem wymagają powiązania zdarzenia z dokumentem, a nie z .modal, ponieważ to tylko dołącza do istniejącego moduły.

Fiddle tutaj.

Siedem grzechów głównych
źródło
2
Czy mogę zasugerować użycie maksymalnego indeksu z otwartych modów w celu ustalenia bazowego indeksu z zamiast stałej wartości 1040? stackoverflow.com/a/5680815/2569159
harco gijsbers
12

Stworzyłem wtyczkę Bootstrap, która zawiera wiele pomysłów opublikowanych tutaj.

Demo na Bootply: http://www.bootply.com/cObcYInvpq

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

Rozwiązuje również problem z kolejnymi modami powodującymi, że tło staje się ciemniejsze. Dzięki temu w danym momencie widoczne jest tylko jedno tło:

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

Indeks Z widocznego tła jest aktualizowany zarówno dla zdarzeń, jak show.bs.modali hidden.bs.modal:

$('.modal-backdrop:first').css('z-index', MultiModal.BASE_ZINDEX + (modalIndex * 20));
jhay
źródło
Niezłe rozwiązanie. Oczekuję, że tło będzie ciemniejsze, gdy masz wiele modów, ale rozumiem, dlaczego nie chcesz tego. @AndyBurton Czy możesz dać mi znać, czego brakuje moje rozwiązanie?
A1rPun
@ A1rPun po otwarciu i zamknięciu 2. modalu usunięto paski przewijania, które pozwoliły na przewijanie w 1. modale. IIRC wyglądało na to, ponieważ klasa na ciele została usunięta, gdy 2. modal został zamknięty.
Andy Burton
@AndyBurton Zajmuję się także rozwiązaniem tego problemu.
A1rPun,
11

Podczas rozwiązywania Modów układania przewija się strona główna, gdy jest ona zamknięta i zauważyłem, że nowsze wersje Bootstrap (przynajmniej od wersji 3.0.3) nie wymagają dodatkowego kodu do modulacji stosów.

Możesz dodać więcej niż jeden modal (oczywiście posiadający inny identyfikator) do swojej strony. Jedynym problemem stwierdzonym podczas otwierania więcej niż jednego modalu będzie to, że zamknięcie jednego usuwa modal-openklasę dla selektora nadwozia.

Możesz użyć następującego kodu JavaScript, aby ponownie dodać modal-open:

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

W przypadku, gdy nie potrzebujesz efektu tła dla ułożonego modalu, możesz ustawić data-backdrop="false".

Wersja 3.1.1. naprawiono Naprawiono modalne tło nakładające się na pasek przewijania modalu , ale powyższe rozwiązanie wydaje się działać również z wcześniejszymi wersjami.

Bass Jobsen
źródło
8

Wreszcie rozwiązany. Przetestowałem to na wiele sposobów i działa dobrze.

Oto rozwiązanie dla każdego, kto ma ten sam problem: Zmień Modal.prototype.show (w bootstrap.js lub modal.js)

Z:

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

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

that.enforceFocus()

DO:

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

To najlepszy sposób, jaki znalazłem: sprawdź, ile modałów jest otwartych i zmień indeks Z modalu i tła na wyższą wartość.

Willian Bonho Daiprai
źródło
6

Jeśli szukasz rozwiązania Bootstrap 4, możesz skorzystać z czystego CSS:

.modal.fade {
    background: rgba(0,0,0,0.5);
}
michal.jakubeczy
źródło
Wygląda na to, że działa dobrze ... pomyślałbyś, że to byłby standardowy Bootstrap?
Ben w Kalifornii
3

Spróbuj dodać poniższe do JS podczas bootply

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

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

Wyjaśnienie:

Po zapoznaniu się z atrybutami (za pomocą narzędzia deweloperskiego Chrome) zdałem sobie sprawę, że każda z-indexwartość poniżej 1031umieści rzeczy za tłem.

Więc za pomocą modalnych uchwyty zdarzeń Bootstrap za ustawić z-indexsię 1030. Jeśli #myModal2jest wyświetlany i ustaw z z-indexpowrotem na 1040if#myModal2 jest ukryty.

Próbny

Drzewny
źródło
2

Za każdym razem, gdy uruchamiasz funkcję sys.showModal, zwiększ wartość indeksu Z i ustaw go na nowy 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
źródło
2

Rozwiązaniem tego było dla mnie NIE używanie klasy „fade” na moich modalnych divach.

Tony Schwartz
źródło
2

Żadne rozwiązania skryptowe, używając tylko css, pod warunkiem, że masz dwie warstwy modałów, ustaw 2. modal na wyższy indeks z

.second-modal { z-index: 1070 }

div.modal-backdrop + div.modal-backdrop {
   z-index: 1060; 
}
Liran Barniv
źródło
2

Jeśli chcesz, aby określony modal pojawiał się na innym modale otwartym, spróbuj dodać kod HTML najwyższego modalu po drugim modale div.

To działało dla mnie:

<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" ... />
reformowany
źródło
2

Moje rozwiązanie dla bootstrap 4, pracującego z nieograniczoną głębokością modali i dynamicznym modalem.

$('.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
źródło
Działa idealnie dla mnie
Kapitan Wiewiórka
1

Każdy modal powinien mieć inny identyfikator, a każdy link powinien być ukierunkowany na inny identyfikator modalu. Powinno to być coś takiego:

<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
źródło
1

EDYCJA: Bootstrap 3.3.4 rozwiązał ten problem (i inne problemy modalne), więc jeśli możesz zaktualizować bootstrap CSS i JS, byłoby to najlepsze rozwiązanie. Jeśli nie możesz zaktualizować, poniższe rozwiązanie będzie nadal działać i zasadniczo robi to samo, co bootstrap 3.3.4 (ponownie oblicz i zastosuj padding).

Jak zauważył Bass Jobsen, nowsze wersje Bootstrap mają rozwiązany indeks Z. Klasa otwarta modalnie i prawa dopełniania nadal były dla mnie problemami, ale skrypty zainspirowane rozwiązaniem Yermo Lamersa rozwiązują to. Po prostu upuść go w pliku JS i ciesz się.

$(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'));
});
dotcomly
źródło
1

Sprawdź to! To rozwiązanie rozwiązało problem dla mnie, kilka prostych linii CSS:

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

Oto link do tego, gdzie go znalazłem: Bootply Upewnij się, że .modual, który musi pojawić się na górze, jest drugi w kodzie HTML, aby CSS mógł go znaleźć jako „parzysty”.

Guntar
źródło
1

praca dla otwierania / zamykania wielu modułów

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

Próbny

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

Ivan
źródło
1

Dla mnie te proste reguły scss działały idealnie:

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

Jeśli te reguły powodują, że niewłaściwy modal znajduje się w twoim przypadku, zmień kolejność modalnych div lub zmień (nieparzysty) na (parzysty) w powyższym scss.

Joery
źródło
0

Oto kilka CSS wykorzystujących nth-of-typeselektory, które wydają się działać:

.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
źródło
1
Ok, świetnie, ale ustawiłem trzeci modal i to nie działa. Mam kilka skryptów, które go generują (np. Alerty, pola wyszukiwania itp.) I mogę mieć jednocześnie 3 otwarte moduły (dopóki się nie dowiem). Nie jestem dobry z css, przepraszam, jeśli coś stracę. Jest kod: bootply.com/86975
Willian Bonho Daiprai 10.10.13
0

Miałem podobny scenariusz i po odrobinie prac badawczo-rozwojowych znalazłem rozwiązanie. Chociaż nie jestem świetny w JS, udało mi się napisać małe zapytanie.

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

});
użytkownik3500842
źródło
0

Dodaj zmienną globalną do modal.js

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

// pokaż funkcję wewnątrz dodaj zmienną - 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
źródło
0

Inne rozwiązania nie działały dla mnie od razu po wyjęciu z pudełka. Myślę, że może dlatego, że używam nowszej wersji Bootstrap (3.3.2) .... nakładka pojawiła się na górze modalnego okna dialogowego.

Trochę przebudowałem kod i skomentowałem część, która dostosowywała tło modalne. To rozwiązało problem.

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

Na marginesie, jeśli chcesz użyć tego w AngularJs, po prostu wstaw kod do metody .run () modułu.

ClearCloud8
źródło
0

Niestety nie mam reputacji do komentowania, ale należy zauważyć, że zaakceptowane rozwiązanie z zakodowaną linią bazową indeksu Z 1040 wydaje się być lepsze niż obliczenie zIndex, które próbuje znaleźć maksymalną renderowaną wartość ZIndex na stronie.

Wygląda na to, że niektóre rozszerzenia / wtyczki polegają na zawartości DOM najwyższego poziomu, co sprawia, że ​​obliczenia .Max są tak nieprzyzwoicie duże, że nie mogą już zwiększać zIndex. Powoduje to powstanie modalu, w którym nakładka pojawia się nieprawidłowo nad modalem (jeśli użyjesz narzędzi Firebug / Google Inspector, zobaczysz indeks zI rzędu 2 ^ n - 1)

Nie byłem w stanie wyodrębnić, z jakiego konkretnego powodu różne formy Math.Max ​​dla z-Index prowadzą do tego scenariusza, ale może się zdarzyć i będzie on wydawał się wyjątkowy dla kilku użytkowników. (Moje ogólne testy na przeglądarce stosowały ten kod działający idealnie).

Mam nadzieję, że to komuś pomoże.

Vincent Polite
źródło
0

W moim przypadku problem został spowodowany przez rozszerzenie przeglądarki, które zawiera pliki bootstrap.js, w których zdarzenie show obsłużyło się dwukrotnie i modal-backdropdodano dwa divy, ale podczas zamykania modalu usuwany jest tylko jeden z nich.

Znaleziono to, dodając punkt przerwania modyfikacji poddrzewa do elementu body w chrome, i śledziłem dodawanie modal-backdropdiv.

Amer Sawan
źródło
0
$(window).scroll(function(){
    if($('.modal.in').length && !$('body').hasClass('modal-open'))
    {
              $('body').addClass('modal-open');
    }

});
stara_wiedzma
źródło
Odpowiedzi zawierające tylko kod często nie pomagają wskazać, dlaczego wystąpił problem. Powinieneś dołączyć wyjaśnienie, dlaczego to rozwiązuje problem. Proszę przeczytać Jak napisać dobrą odpowiedź?
FluffyKitten
0

Aktualizacja: 22.01.2019, 13.41 Zoptymalizowałem rozwiązanie przez jhay, który obsługuje także zamykanie i otwieranie tych samych lub różnych okien dialogowych, na przykład przechodząc od jednego szczegółowego danych do drugiego do przodu lub do tyłu.

(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
źródło
0

Sprawdź liczbę modali i dodaj wartość do tła jako indeks 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
źródło