오버레이가 뒤가 아닌 첫 번째 모달 위에 표시되어야합니다.
나는 변경 시도 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);
답변이 수락되었지만이 문제를 해결하기 위해 부트 스트랩을 해킹하지 않는 것이 좋습니다.
shown.bs.modal 및 hidden.bs.modal 이벤트 핸들러를 연결하고 z- 색인을 조정하여 동일한 효과를 쉽게 얻을 수 있습니다.
조금 더 많은 정보는 여기에 있습니다.
이 솔루션은 임의로 깊이있는 스택 모달에서 자동으로 작동합니다.
스크립트 소스 코드 :
$(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
body 요소 에서 클래스를 복원해야합니다 . jsfiddle.net/vkyjocyn
StriplingWarrior의 제안과 A1rPun의 답변을 결합하여 다음과 같이했습니다.
$(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');
사실 이후에 추가 된 동적 모달에서도 작동하며 두 번째 스크롤 막대 문제를 제거합니다. 가장 주목할만한 점은 동적 모달을 사용하여 이벤트를 .modal 대신 문서에 바인딩해야하기 때문에 Bootbox 경고의 유효성 검사 피드백과 함께 모달 내부 양식을 모달 내부에 통합하는 것이 었습니다. 모달.
여기에 게시 된 많은 아이디어를 통합 한 Bootstrap 플러그인을 만들었습니다.
Bootply 데모 : http://www.bootply.com/cObcYInvpq
깃 허브 : 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));
스태킹 모달을 해결할 때 메인 페이지가 닫히면 스크롤됩니다 됩니다. 최신 버전의 부트 스트랩 (최소 버전 3.0.3 이후)에는 모달을 스택하기 위해 추가 코드가 필요하지 않습니다.
페이지에 둘 이상의 모달 (물론 다른 ID를 가짐)을 추가 할 수 있습니다. 둘 이상의 모달을 열 때 발견되는 유일한 문제는modal-open
본문 선택기 클래스가 입니다.
다음 자바 스크립트 코드를 사용하여 다음을 다시 추가 할 수 있습니다 modal-open
.
$('.modal').on('hidden.bs.modal', function (e) {
if($('.modal').hasClass('in')) {
$('body').addClass('modal-open');
}
});
스택 모달에 배경 효과가 필요하지 않은 경우 설정할 수 있습니다 data-backdrop="false"
.
버전 3.1.1. 고정 모달 배경 화면이 모달의 스크롤 막대를 오버레이 하지만 위의 솔루션은 이전 버전에서도 작동하는 것으로 보입니다.
마침내 해결되었습니다. 여러 가지 방법으로 테스트했으며 정상적으로 작동합니다.
동일한 문제가있는 사람을위한 해결책은 다음과 같습니다. (bootstrap.js 또는 modal.js에서) Modal.prototype.show 함수 변경
에서:
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);
}
bootply에서 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
배경이 뒤 떨어질 것임을 깨달았습니다 .
부트 스트랩의 모달 이벤트 핸들을 사용하여 z-index
를로 설정 했습니다 1030
. 경우는 #myModal2
표시와 설정 z-index
을 다시 1040
하면 #myModal2
숨겨져 있습니다.
sys.showModal 함수 증가 z-index를 실행할 때마다 새 모달로 설정하십시오.
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');
특정 모달이 다른 열린 모달 위에 나타나도록 하려면 다른 모달 뒤에 최상위 모달의 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', '');
});
각 모달마다 다른 ID를 부여해야하며 각 링크는 다른 모달 ID를 대상으로해야합니다. 따라서 다음과 같아야합니다.
<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>
...
편집 : Bootstrap 3.3.4는이 문제 (및 기타 모달 문제)를 해결 했으므로 부트 스트랩 CSS와 JS를 업데이트 할 수 있다면 가장 좋은 해결책입니다. 아래 솔루션을 업데이트 할 수없는 경우에도 여전히 작동하며 부트 스트랩 3.3.4 (패딩 재 계산 및 적용)와 동일한 기능을 수행합니다.
Bass Jobsen이 지적했듯이 최신 버전의 Bootstrap은 z-index를 해결했습니다. 모달 오픈 클래스와 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'));
});
개방 / 폐쇄 멀티 모달 작업
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);
}
});
});
데모
다음은 nth-of-type
작동 하는 선택기를 사용하는 CSS입니다 .
.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
비슷한 시나리오가 있었으며 약간의 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);
});
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
다른 솔루션은 즉시 사용할 수 없었습니다. 아마도 최신 버전의 부트 스트랩 (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-index의 하드 코딩 된 기준을 가진 수용 된 솔루션이 페이지에서 렌더링되는 최대 zIndex를 찾으려고하는 zIndex 계산보다 우월한 것으로 보입니다.
특정 확장 기능 / 플러그인은 최상위 DOM 콘텐츠에 의존하여 .Max 계산을 음란하게 크게 만들어 zIndex를 더 이상 증가시킬 수없는 것으로 보입니다. 이로 인해 모달 위에 오버레이가 잘못 나타나는 모달이 발생합니다 (Firebug / Google Inspector 도구를 사용하는 경우 2 ^ n-1 순서로 zIndex가 표시됨)
z-Index 용 Math.Max의 다양한 형식이이 시나리오로 이어지는 특정 이유를 분리 할 수 없었지만 발생할 수 있으며 일부 사용자에게 고유하게 표시됩니다. (브라우저 스택에 대한 일반적인 테스트 에서이 코드가 완벽하게 작동했습니다).
이것이 누군가를 돕기를 바랍니다.
$(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');