オーバーレイが背面ではなく、最初のモーダルの上に表示される必要があります。
私は変更しようとしたz-index
のを.modal-backdrop
、それが混乱になります。
同じページに3つ以上のモーダルがある場合があります。
オーバーレイが背面ではなく、最初のモーダルの上に表示される必要があります。
私は変更しようとしたz-index
のを.modal-backdrop
、それが混乱になります。
同じページに3つ以上のモーダルがある場合があります。
回答:
これに対する多くの修正を確認した後、それらのどれも私が必要としていたものとまったく同じではなかったので、@ YermoLamersと@Ketwarooに触発されたさらに短い解決策を思い付きました。
背景z-indexの修正
このソリューションでは、イベントがトリガーされたときにが作成されないsetTimeout
ため、aを使用します。.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-indexが気に入らない場合は、次のようにページで最も高いz-indexを計算できます。
var zIndex = Math.max.apply(null, Array.prototype.map.call(document.querySelectorAll('*'), function(el) {
return +el.style.zIndex;
})) + 10;
スクロールバーの修正
ページにブラウザの高さを超えるモーダルがある場合、2番目のモーダルを閉じるときにスクロールできません。これを修正するには:
$(document).on('hidden.bs.modal', '.modal', function () {
$('.modal:visible').length && $(document.body).addClass('modal-open');
});
バージョン
このソリューションは、ブートストラップ3.1.0〜3.3.5でテストされています
.not(this)
で機能させるために、2行目に追加されたマイナーな変更を加える必要がありました var zIndex = 1040 + (10 * $('.modal:visible').not(this).length);
回答は受け入れられましたが、これを修正するためにブートストラップをハッキングしないことを強くお勧めします。
shows.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
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');
事後に追加された動的モーダルでも機能し、2番目のスクロールバーの問題を取り除きます。モーダル内のフォームとBootboxアラートからの検証フィードバックを統合することは、これが動的モーダルを使用しているため、イベントを.modalではなくドキュメントにバインドする必要があるためです。モーダル。
ここに投稿された多くのアイデアを組み込んだBootstrapプラグインを作成しました。
Bootplyのデモ:http ://www.bootply.com/cObcYInvpq
Github:https : //github.com/jhaygt/bootstrap-multimodal
また、連続するモーダルが背景をどんどん暗くする問題にも対処します。これにより、常に1つの背景のみが表示されます。
if(modalIndex > 0)
$('.modal-backdrop').not(':first').addClass('hidden');
表示される背景のZ-indexは、イベントshow.bs.modal
とhidden.bs.modal
イベントの両方で更新されます。
$('.modal-backdrop:first').css('z-index', MultiModal.BASE_ZINDEX + (modalIndex * 20));
スタックモーダルを解決すると、メインページが閉じたときにメインページがスクロールします。新しいバージョンのBootstrap(少なくともバージョン3.0.3以降)では、モーダルをスタックするために追加のコードは必要ありません。
ページに複数のモーダル(もちろん異なるIDを持つ)を追加できます。複数のモーダルを開くときに見つかった唯一の問題は、1つを閉じると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);
}
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>
...
編集:ブートストラップ3.3.4はこの問題(およびその他のモーダル問題)を解決したので、ブートストラップCSSおよびJSを更新できる場合は、これが最善の解決策になります。更新できない場合、以下のソリューションは引き続き機能し、基本的にブートストラップ3.3.4と同じことを行います(再計算してパディングを適用します)。
Bass Jobsenが指摘したように、Bootstrapの新しいバージョンではz-indexが解決されています。modal-openクラスと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
同様のシナリオがあり、少しの研究開発の結果、解決策が見つかりました。私は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
// add変数内の関数を表示-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-indexのハードコードされたベースラインを使用した承認済みのソリューションは、ページにレンダリングされている最大のzIndexを見つけようとするzIndexの計算よりも優れているようです。
一部の拡張機能/プラグインは、最上位のDOMコンテンツに依存しているため、.Maxの計算が非常に多くなり、zIndexをこれ以上インクリメントできないようです。これにより、モーダル上にオーバーレイが正しく表示されないモーダルが発生します(Firebug / Google Inspectorツールを使用すると、2 ^ n-1のオーダーのzIndexが表示されます)
Math.Max for z-Indexのさまざまな形式がこのシナリオにつながる具体的な理由を特定することはできませんでしたが、それは発生する可能性があり、一部のユーザーに固有のように見えます。(ブラウザースタックでの私の一般的なテストでは、このコードは完全に機能していました)。
これが誰かを助けることを願っています。
$(window).scroll(function(){
if($('.modal.in').length && !$('body').hasClass('modal-open'))
{
$('body').addClass('modal-open');
}
});
更新:2019年1月22日、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-indexとして背景に追加します
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');