多种模态叠加

2020/10/19 10:42 · javascript ·  · 0评论

我需要将叠加层显示在第一个模态上方,而不是在背面。

模态叠加在后面

我试图改变z-index.modal-backdrop,但它成了一个烂摊子。

在某些情况下,我在同一页面上有两个以上的模态。

在看到许多修复程序之后,它们都不是我真正需要的,因此我想出了一个更短的解决方案,该解决方案的灵感来自@YermoLamers和@Ketwaroo。

背景Z索引修复

此解决方案使用a,
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页面上创建的每个内容(甚至是动态模式)
  • 背景立即覆盖之前的模态

jsfiddle示例

如果由于某种原因您不喜欢硬编码的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');
});

版本

此解决方案已在Bootstrap 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的建议,这是一个简短的版本,似乎正常。即使使用诸如淡入/淡出之类的基本动画,甚至疯狂的蝙蝠侠报纸也会旋转。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');
});

结合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-index在show.bs.modalhidden.bs.modal事件上都进行了更新

$('.modal-backdrop:first').css('z-index', MultiModal.BASE_ZINDEX + (modalIndex * 20));

解决堆栈模式时,在关闭页面时滚动主页,我发现较新版本的Bootstrap(至少从版本3.0.3起)不需要任何其他代码即可堆栈模式。

您可以向页面添加多个模式(当然会有不同的ID)。打开多个模式时发现的唯一问题是,关闭一个模式会删除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的dev工具)之后,我意识到z-index下面的任何1031都会使事情变得毫无根据。

因此,通过使用引导程序的模式事件句柄,我将设置z-index1030如果#myModal2显示z-index1040if ,则将back设置if #myModal2

演示版

我对引导程序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', '');
});

每次运行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');

对我来说,解决方案是不要在我的模式div上使用“ 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" ... />

每个模态应被赋予不同的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已经解决了这个问题(以及其他模式问题),因此,如果您可以更新Bootstrap CSS和JS,那将是最好的解决方案。如果您无法更新,则下面的解决方案仍然可以使用,并且实际上与Bootstrap 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'));
});

看一下这个!此解决方案为我解决了问题,几行简单的CSS行:

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

这是我找到它的地方的链接:Bootply
只要确保需要在Top上显示的.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);
       }
    });
});

演示版

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

对我来说,这些简单的scss规则非常有效:

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

如果这些规则导致错误的模态在您的情况下居于首位,则可以更改模态div的顺序,或者在上述scss中将(奇数)更改为(偶数)。

这是一些使用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">&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);

});

在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-index硬编码基线的公认解决方案似乎要比试图查找页面上呈现的最大zIndex的zIndex计算要好。

似乎某些扩展程序/插件依赖于顶级DOM内容,这使得.Max计算值是如此之大,以至于它无法进一步增加zIndex。这会导致模态,使覆盖图错误地显示在模态上(如果您使用Firebug / Google Inspector工具,则zIndex的顺序为2 ^ n-1)

我还无法找出导致z-Index的各种形式的Math.Max导致这种情况的具体原因,但是它可能发生,并且对于某些用户而言,它将是唯一的。(我在browserstack上进行的常规测试使此代码运行正常)。

希望这对某人有帮助。

就我而言,问题是由包含bootstrap.js文件的浏览器扩展引起的,其中show事件处理了两次,而两次 modal-backdrop添加了div,但是在关闭模式时,仅删除其中的一个。

通过向chrome中的body元素添加子树修改断点来发现,并跟踪添加modal-backdropdiv。

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

该代码仅适用于引导程序4。其他代码中的问题是如何选择模式背景。模态显示后,如果对实际模态使用jQuery next select会更好。

$(document).on('show.bs.modal', '.modal', function () {
        var zIndex = 1040 + (10 * $('.modal').length);
        var model = $(this);
        model.css('z-index', zIndex);
        model.attr('data-z-index', zIndex);
    });

    $(document).on('shown.bs.modal', '.modal', function () {
        var model = $(this);
        var zIndex = model.attr('data-z-index');
        model.next('.modal-backdrop.show').css('z-index', zIndex - 1);
  
  });

Bootstrap 4.5的简单解决方案

.modal.fade {
  background: rgba(0, 0, 0, 0.5);
}

.modal-backdrop.fade {
  opacity: 0;
}
本文地址:http://javascript.askforanswer.com/duozhongmotaidiejia.html
文章标签: ,   ,   ,   ,  
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!