Мені потрібно, щоб накладка була вище першого модаля, а не ззаду.
Я спробував змінити z-index
з .modal-backdrop
, але це стає безлад.
У деяких випадках у мене на одній сторінці є більше двох модалів.
Мені потрібно, щоб накладка була вище першого модаля, а не ззаду.
Я спробував змінити 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
створеного на сторінці (навіть динамічних режимів)Якщо вам не подобається твердокодований z-індекс з будь-якої причини, ви можете обчислити найвищий z-індекс на сторінці, як це:
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
.not(this)
до другого рядка), щоб вона працювала з завантажувачем дати завантаження var zIndex = 1040 + (10 * $('.modal:visible').not(this).length);
Я усвідомлюю, що відповідь прийнято, але настійно рекомендую не зламати завантажувальну програму, щоб виправити це.
Ви можете досить легко досягти такого ж ефекту, підключивши показані покажчики подій.
Трохи більше інформації можна отримати тут.
Це рішення працює автоматично з довільно глибокими стеками модалів.
Вихідний код сценарію:
$(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, це, здається, працює добре. Навіть з базовими анімаціями, такими як згасання / вимкнення, і навіть божевільні газети Бетмена обертаються. 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
клас на елемент тіла: 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, який включає багато ідей, розміщених тут.
Демонстрація при завантаженні: 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));
При вирішенні режимів Stacking прокручується головна сторінка, коли одна закрита, я виявив, що новіші версії Bootstrap (принаймні з версії 3.0.3) не потребують додаткового коду для складання модалів.
На свою сторінку можна додати більше одного способу (звичайно, має інший ідентифікатор). Єдиною проблемою, виявленою при відкритті декількох модалів, буде те, що закрити один видалити modal-open
клас для вибору елемента.
Ви можете використовувати наступний код Javascript для повторного додавання modal-open
:
$('.modal').on('hidden.bs.modal', function (e) {
if($('.modal').hasClass('in')) {
$('body').addClass('modal-open');
}
});
У випадку, коли не потрібен ефект задника для складеного модалу, ви можете встановити data-backdrop="false"
.
Версія 3.1.1. фіксованого Фікс модального фон накладання скроллбар модального в , але вище рішення представляється також працювати з більш ранніми версіями.
Нарешті вирішено. Я перевірив це багатьма способами і працює чудово.
Ось рішення для всіх, хто має ту саму проблему: Змініть функцію 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()
ДО:
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-індекс модала та фону на більш високе значення.
Якщо ви шукаєте рішення Bootstrap 4, є легкий за допомогою чистого CSS:
.modal.fade {
background: rgba(0,0,0,0.5);
}
Спробуйте додати наступне до свого JS під час завантаження
$('#myModal2').on('show.bs.modal', function () {
$('#myModal').css('z-index', 1030); })
$('#myModal2').on('hidden.bs.modal', function () {
$('#myModal').css('z-index', 1040); })
Пояснення:
Погравши з атрибутами (використовуючи інструмент розробки Chrome), я зрозумів, що будь-яке z-index
значення нижче 1031
поставить речі на задній план.
Таким чином , за допомогою модальної ручки подій Bootstrap, я встановити z-index
в 1030
. Якщо #myModal2
відображається, встановіть z-index
спинку, 1040
якщо #myModal2
приховано.
Кожен раз, коли ви запускаєте sys.showModal, збільшуючи z-індекс і встановлюйте його на новий модальний.
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');
Рішенням цього для мене було НЕ використовувати клас "fade" на моїх модальних дівах.
Жодне рішення скрипту, використовуючи лише css, якщо ви маєте два шари модалів, встановіть другий модаль на більш високий z індекс
.second-modal { z-index: 1070 }
div.modal-backdrop + div.modal-backdrop {
z-index: 1060;
}
Якщо ви хочете, щоб певний модал відображався поверх іншого відкритого модалу, спробуйте додати HTML самого верхнього модаля після іншого div
.
Це працювало для мене:
<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" ... />
Моє рішення для завантажувальної програми 4, робота з необмеженою глибиною модалів та динамічним модальним режимом.
$('.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 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>
...
EDIT: Bootstrap 3.3.4 вирішив цю проблему (та інші модальні проблеми), тому якщо ви можете оновити CSS та JS для завантаження, це було б найкращим рішенням. Якщо ви не можете оновити рішення нижче, воно все одно спрацює і по суті робить те ж саме, що і для завантажувальної версії 3.3.4 (перерахунок та застосування накладки).
Як зазначив Bass Jobsen, новіші версії Bootstrap вирішили z-індекс. Модально-відкритий клас та підкладка-право все ще були проблемами для мене, але цей сценарій, натхненний рішенням 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'));
});
Заціни! Це рішення вирішило проблему для мене, кілька простих рядків CSS:
.modal:nth-of-type(even) {
z-index: 1042 !important;
}
.modal-backdrop.in:nth-of-type(even) {
z-index: 1041 !important;
}
Ось посилання на те, де я його знайшов: Bootply Просто переконайтеся, що .modual, який повинен з’явитися вгорі, є другим у HTML-коді, щоб CSS міг знайти його як "рівний".
робота для відкриття / закриття мультимодалів
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);
}
});
});
Демо
Для мене ці прості правила scss прекрасно працювали:
.modal.show{
z-index: 1041;
~ .modal.show{
z-index: 1043;
}
}
.modal-backdrop.show {
z-index: 1040;
+ .modal-backdrop.show{
z-index: 1042;
}
}
Якщо ці правила призводять до того, що неправильний модал у вашому випадку перебуває на вершині, або змініть порядок модальних дівок, або змініть (непарне) на (парне) вище в scss.
Ось деякі CSS за допомогою nth-of-type
селекторів, які, здається, працюють:
.modal:nth-of-type(even) {
z-index: 1042 !important;
}
.modal-backdrop.in:nth-of-type(even) {
z-index: 1041 !important;
}
Завантаження: http://bootply.com/86973
У мене був аналогічний сценарій, і після невеликих досліджень і розробок я знайшов рішення. Хоча я не чудовий в 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);
});
Додайте глобальну змінну в 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
Інші рішення не спрацювали зі мною. Я думаю, можливо, тому, що я використовую більш нову версію 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 () модуля.
На жаль, я не маю репутації коментувати, але слід зазначити, що прийняте рішення із твердо кодованою базовою лінією 1040 z-індексу, здається, перевершує розрахунок zIndex, який намагається знайти максимальний zIndex, що відображається на сторінці.
Здається, що деякі розширення / плагіни покладаються на вміст DOM верхнього рівня, що робить обчислення .Max таким нецензурно великим числом, що він більше не може збільшувати zIndex. Це призводить до модалу, коли накладка з’являється над модалом неправильно (якщо ви використовуєте Firebug / Google Інспектор Google, ви побачите zIndex в порядку 2 ^ n - 1)
Я не зміг виділити, до якої конкретної причини різні форми Math.Max для z-Index призводять до цього сценарію, але це може статися, і воно здасться унікальним для кількох користувачів. (У моїх загальних тестах на стек браузера цей код працював ідеально).
Сподіваюся, що це комусь допоможе.
У моєму випадку проблема була викликана розширенням для браузера, яке включає файли bootstrap.js, де показ події оброблявся двічі та два modal-backdrop
додаються діви, але при закритті модального видаляється лише один з них.
Виявив, що додавши точку перериву модифікації підрівню до елемента тіла в хромі та відстеживши додавання modal-backdrop
дівок.
$(window).scroll(function(){
if($('.modal.in').length && !$('body').hasClass('modal-open'))
{
$('body').addClass('modal-open');
}
});
Оновлення: 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));
Перевірте кількість модалів і додайте значення для фону як 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');