Мне нужно, чтобы наложение показывалось выше первого модального, а не обратно.
$('#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>
Я попытался изменить z-index
в .modal-backdrop
, но он стал беспорядок.
В некоторых случаях у меня есть более двух модалов на одной странице.
После просмотра многих исправлений для этого, и ни один из них не был именно тем, что мне нужно, я придумал еще более короткое решение, вдохновленное @YermoLamers и @Ketwaroo.
Исправление z-индекса заднего плана
Это решение использует setTimeout
, потому что .modal-backdrop
не создается при срабатывании события show.bs.modal
.
$(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);
});
.modal
, созданного на странице (даже динамических модалов).Если вам не нравится hardcoded z-index по любой причине, вы можете рассчитать самый высокий z-index на странице следующим образом:
var zIndex = Math.max.apply(null, Array.prototype.map.call(document.querySelectorAll('*'), function(el) {
return +el.style.zIndex;
})) + 10;
Фиксация прокрутки
Если на вашей странице есть модальный размер, превышающий высоту браузера, вы не можете прокручивать его при закрытии второго модального. Чтобы исправить это, добавьте:
$(document).on('hidden.bs.modal', '.modal', function () {
$('.modal:visible').length && $(document.body).addClass('modal-open');
});
Версии
Это решение протестировано с помощью бутстрапа 3.1.0 - 3.3.5
Я понимаю, что ответ принят, но я настоятельно рекомендую не взламывать загрузчик, чтобы это исправить.
Вы можете довольно легко добиться того же эффекта, подключив обработчики событий show.bs.modal и hidden.bs.modal и настроив там z-index.
Немного больше информации доступно здесь.
Это решение работает автоматически с произвольно глубокими стеками модов.
Исходный код скрипта:
$(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, похоже, работает нормально. Даже с базовыми анимациями, такими как увядание в/из и даже сумасшедшая газета 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');
});
modal-open
класс для элемента body: jsfiddle.net/vkyjocyn
Объединив ответ A1rPun с предложением StriplingWarrior, я придумал следующее:
$(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');
Работает даже для динамических модалов, добавленных после факта, и удаляет проблему второго прокрутки. Наиболее примечательной вещью, которую я нашел полезной для нее, была интеграция форм внутри модалов с обратной связью по валидации с помощью предупреждений Bootbox, поскольку они используют динамические модальности и, следовательно, требуют, чтобы вы привязывали событие к документу, а не к .modal, поскольку это только привязывает его к существующим модальности.
Я создал плагин Bootstrap, который содержит много идей, размещенных здесь.
Демо на Bootply: http://www.bootply.com/cObcYInvpq
Github: https://github.com/jhaygt/bootstrap-multimodal
Он также решает проблему с последующими модальностями, заставляя фон становиться темнее и темнее. Это гарантирует, что в любой момент времени будет отображаться только один фон:
if(modalIndex > 0)
$('.modal-backdrop').not(':first').addClass('hidden');
Z-индекс видимого фона обновляется как в событиях show.bs.modal
, так и hidden.bs.modal
:
$('.modal-backdrop:first').css('z-index', MultiModal.BASE_ZINDEX + (modalIndex * 20));
При решении Складные модалы прокручивают главную страницу при закрытии. Я обнаружил, что более новые версии Bootstrap (по крайней мере с версии 3.0.3) не требуют никаких дополнительных код для стека модалов.
На страницу можно добавить несколько модальных (разумеется, разных ID). Единственная проблема, обнаруженная при открытии более чем одного модала, будет заключаться в том, что при закрытии один из них удаляет класс modal-open
для селектора body.
Вы можете использовать следующий код Javascript для повторного добавления modal-open
:
$('.modal').on('hidden.bs.modal', function (e) {
if($('.modal').hasClass('in')) {
$('body').addClass('modal-open');
}
});
В случае, когда не требуется эффект фона для сложного модального кода, вы можете установить data-backdrop="false"
.
Версия 3.1.1. fixed Исправить модальный фон, накладывая модальную полосу прокрутки, но вышеприведенное решение, похоже, также работает с более ранними версиями.
Наконец, решено. Я тестировал его разными способами и прекрасно работал.
Вот решение для тех, у кого такая же проблема: Измените функцию Modal.prototype.show(в bootstrap.js или modal.js)
С
if (transition) {
that.$element[0].offsetWidth // force reflow
}
that.$element
.addClass('in')
.attr('aria-hidden', false)
that.enforceFocus()
TO:
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()
Это лучший способ, который я нашел: проверить, сколько модалов открыто, и изменить z-индекс модального и заднего фона на более высокое значение.
Попробуйте добавить следующее в ваш JS при загрузке
$('#myModal2').on('show.bs.modal', function () {
$('#myModal').css('z-index', 1030); })
$('#myModal2').on('hidden.bs.modal', function () {
$('#myModal').css('z-index', 1040); })
Объяснение:
Поработав с атрибутами (используя инструмент Chrome dev), я понял, что любое значение z-index
ниже 1031
поставит все на задний план.
Таким образом, используя загрузчики модальных событий начальной загрузки, я установил z-index
на 1030
. Если #myModal2
отображается и установите z-index
обратно в 1040
если #myModal2
скрыт.
Каждый раз, когда вы запускаете z-index с расширением zys.showModal, установите его в новый модальный.
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');
работа для открытых/закрытых мультимодалов
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);
}
});
});
Демо
Решение этого для меня было НЕ использовать класс "fade" для моих модальных div.
EDIT: Bootstrap 3.3.4 решил эту проблему (и другие модальные проблемы), поэтому, если вы можете обновить свой bootstrap CSS и JS, это было бы лучшим решением. Если вы не можете обновить решение ниже, оно все равно будет работать и, по сути, делает то же самое, что и bootstrap 3.3.4 (пересчитать и применить дополнение).
Как отметил Басс Джессен, более новые версии Bootstrap имеют z-индекс. Модально-открытый класс и padding-right все еще были для меня проблемой, но эти сценарии, вдохновленные решением Yermo Lamers, решают его. Просто опустите его в свой JS файл и наслаждайтесь.
$(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'));
});
Каждому модалю должен быть присвоен другой идентификатор, и каждая ссылка должна быть нацелена на другой идентификатор модальности. Так должно быть что-то вроде этого:
<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>
...
Обновление: 22.01.2019, 13.41 Я оптимизировал решение с помощью jhay, который также поддерживает закрытие и открытие одинаковых или разных диалогов, например, при переходе от одной детализации данных к другой вперед или назад.
(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));
Если вы ищете решение Bootstrap 4, есть простое решение с использованием чистого CSS:
.modal.fade {
background: rgba(0,0,0,0.5);
}
Иногда последовательность может вызвать беспорядок! Напишите сначала модальный сначала, затем второй модальный
Нет сценариев решения, используя только CSS, если у вас есть два слоя модалов, установите 2-й модал на более высокий индекс z
.second-modal { z-index: 1070 }
div.modal-backdrop + div.modal-backdrop {
z-index: 1060;
}
Проверьте это! Это решение решило проблему для меня, несколько простых линий CSS:
.modal:nth-of-type(even) {
z-index: 1042 !important;
}
.modal-backdrop.in:nth-of-type(even) {
z-index: 1041 !important;
}
Вот ссылка на то, где я ее нашел: Bootply Просто убедитесь, что .modual, который должен появиться в Top, является вторым в HTML-коде, поэтому CSS может найти его как "четный".
$(window).scroll(function(){
if($('.modal.in').length && !$('body').hasClass('modal-open'))
{
$('body').addClass('modal-open');
}
});
В моем случае проблема была вызвана расширением браузера, которое включает файлы bootstrap.js, в которых событие show обработано дважды, и два div modal-backdrop
добавлены, но при закрытии модальности удаляется только один из них.
Обнаружено, что добавив точку останова модификации поддерева к элементу body в chrome и отслеживая добавление div modal-backdrop
.
К сожалению, у меня нет репутации для комментариев, но следует отметить, что принятое решение с жестко запрограммированным базовым индексом 1040 z-index, по-видимому, превосходит расчет zIndex, который пытается найти максимальное значение zIndex, отображаемое на страница.
Похоже, что некоторые расширения/плагины полагаются на контент DOM верхнего уровня, который делает вычисление .Max таким неприлично большим числом, что он больше не может увеличивать zIndex. Это приводит к модальности, когда наложение появляется над модальным неверно (если вы используете инструменты Firebug/Google Inspector, вы увидите zIndex порядка 2 ^ n - 1)
Мне не удалось выделить, какова конкретная причина, по которой различные формы Math.Max для z-Index приводят к этому сценарию, но это может произойти, и оно будет уникальным для нескольких пользователей. (Мои общие тесты в браузереста показали, что этот код работает отлично).
Надеюсь, это поможет кому-то.
Другие решения не работали для меня из коробки. Я думаю, возможно, потому, что я использую более новую версию Bootstrap (3.3.2).... наложение появилось поверх модального диалога.
Я немного обработал код и закомментировал часть, которая корректировала модальный фон. Это устранило проблему.
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');
});
В качестве побочного примечания, если вы хотите использовать это в AngularJs, просто поместите код внутри вашего модуля .run().
Попробуйте http://nakupanda.github.io/bootstrap3-dialog/#opening-multiple-dialogs
Он должен легко решить вашу проблему.
Добавить глобальную переменную в modal.js
var modalBGIndex = 1040; // modal backdrop background
var modalConIndex = 1042; // modal container data
//показать функцию внутри переменной добавления - 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
У меня был похожий сценарий, и после немного R & D я нашел решение. Хотя я не очень хорош в JS, мне удалось записать небольшой запрос.
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">×</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);
});
Вот несколько CSS с помощью селекторов nth-of-type
, которые, кажется, работают:
.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. сначала укажите любой идентификатор вашего модального всплывающего окна, которое вы хотите дать perioty eX: id = 'testmodal'
2. В стиле вы можете дефинировать css, как показано ниже, значение 2147483647 - это самое высокое значение, которое вы можете указать как индекс z.
#testmodal.fade.in{
z-index: 2147483647;
}
этот класс css будет применяться к вашему модалю, в который вы хотите применить, поскольку он сначала будет искать id = testmodal если у вас более одного всплывающего окна, вы можете установить "z-index" в соответствии с вашим приоритетом ", означает, что более высокий приоритет получит более высокое значение z-index