bootstrap多层modal的相关问题

1、bootstrap多层modal关闭后无滚动问题

原文链接:bootstrap多层modal关闭后无滚动问题

bootstrap中如果在模态框弹出模态框,即多重模态框,那么在关闭模态框后,上一级的模态框无法滚动,而且滚动事件会穿透到body层。

原理是只要有modal被打开,body会被赋予modal-open这个类,使其overflow变为hidden,无法滚动;而只要有modal被关闭,body的modal-open这个类就会被remove掉。

所以解决方法如代码,非最老的一层modal监听隐藏事件,为body重新添加modal-open类。

$(".notLastModal").on("hidden.bs.modal",function(){
  $(document.body).addClass("modal-open");
});

2、Bootstrap页面中多个modal报“too much recursion”

原文链接:Bootstrap页面中多个modal报”too much recursion”错误的解决方案

在用Bootstrap时候发现,如果我在一个弹出的modal中再弹出一个modal的时候,js就会报错“too much recursion”,从而会影响modal中弹出的那个modal里面的一些jquery插件的使用

原因:无限递归调用
无限重复bug:当一个任务类型为同步类型,并且在任务中没有释放资源(即该任务不是最后一个任务,并且是同步任务),其下一个任务为无限重复(repeatForever)时,出现无尽递归错误(too much recursion)。

解决方案:把$.fn.modal.Constructor.prototype.enforceFocus 方法去掉就可以了。

在Bootstap.js 包含以后加上:

$.fn.modal.Constructor.prototype.enforceFocus = function () {};

这样就不会报错了!

我用的是bootstrap.min.js,效果是一样的
在这里插入图片描述

其他

关于问题(Bootstrap页面中多个modal报“too much recursion”)的其他解决办法

方法一

参考解决思路
原文链接:Bootstrap同时弹出多个模态窗口Modal时的几个问题

Bootstrap中的modal组件是使用率比较高的组件之一,可modal本身对于同一个页面同时弹出多个modal的情况支持并不是很好,有些人说应该尽量避免同时弹出多个modal,应该关闭之前的modal再弹出新的modal,确实,弹出多个modal会导致页面看起来比较混乱,但不管出于什么原因,我们经常还是会碰到需要弹出多个modal的情况。

首先,碰到的第一个问题就是如果弹出多个modal,会出现相互遮盖的情况。bootstrap对modal的弹层固定了一个z-index,笔者使用的bootstrap版本为3.3.4,z-index值为1050,不同版本可能会不同。使用相同的z-index就会导致后面的弹出层无法遮住前面的弹出层的情况。这时,我们想,如果之后每个弹出层的z-index都能递增就好了,于是,笔者增加了如下代码:

$(document).on('hidden.bs.modal','.modal',function(e){
    $(this).css("z-index", 1050);
    dashboard.opts.modalLevel--;
});
$(document).on('show.bs.modal','.modal',function(e){
    $(this).css("z-index", 1050+dashboard.opts.modalLevel);
    dashboard.opts.modalLevel++;
});

在每一个modal显示前,先获取当前弹层的数量,将z-index在1050的基础上加上弹层数量,dashboard.opts.modalLevel这个就是笔者存储弹层数量的一个变量,显示和隐藏时都分别更新这个值,这样就实现了z-index的递增。

其次,弹出第一个窗口时,窗口默认是水平居中的,接着弹出第二个,会发现窗口发生了偏移,实际上是第二个窗口被设置了padding-left:15px。笔者开始以为这时作者特意设置的,这样能显出层次感,每个新弹出的窗口相对上一个进行一定偏移,但是,笔者接着弹出第三个窗口,发现padding-left还是15px,并没有增加,于是和第二个窗口重合了。

上面的测试还是在所有modal处于同一级dom节点的情况,如果是modal里面的modal,这一偏移就会导致15px的内容被遮盖了,很不幸,笔者就是这种情况。最初,笔者在新弹出的modal的shown事件上,将padding-left值进行还原,这样勉强可用,但是会出现modal突然移动的情况,对于有些强迫症的同学可能接受不了,于是笔者进一步研究了一下源码。

modal里面有一个bodyIsOverflowing属性,字面上理解是body是否溢出窗口,是在checkScrollbar方法里面计算的:

Modal.prototype.checkScrollbar = function () {
  var fullWindowWidth = window.innerWidth
  if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8
    var documentElementRect = document.documentElement.getBoundingClientRect()
    fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left)
  }
  this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth
  this.scrollbarWidth = this.measureScrollbar()
}

笔者坐看右看,感觉这个值的意思好像是反了,方法里面,body的可见区域如果小于窗口的可见区域,bodyIsOverflowing值就是true,小于,不是应该没溢出吗。

adjustDialog方法对modal的padding-left和padding-right值进行了设置:

Modal.prototype.adjustDialog = function () {
  var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight

  this.$element.css({
    paddingLeft:  !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '',
    paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : ''
  })
}

这里可以看出来了,原来那个padding-left值15px是滚动条的宽度,padding值不是15就是0,没有其他值,跟笔者最开始想的层次结构是不相关的。第一次弹出时,笔者的document.body.clientWidth是1425,小于fullWindowWidth的1440,中间正好差个滚动条的宽度15,第二次弹出时,由于遮罩将滚动条也遮住了,document.body.clientWidth变成了1440,等于窗口的宽度,所以最后偏移了15px。笔者觉得bodyIsOverflowing是关键,body的width小于和等于window的width应该是一样的,所以笔者将代码修改成了如下:

this.bodyIsOverflowing = document.body.clientWidth <= fullWindowWidth

笔者继续查看了3.3.5的源码以及4的源码,发现计算值都还是使用的小于,可能作者确实不建议同时使用多个modal,并没有处理这种情况。

另外,如果要实现每个弹出框相对于前一个弹出框进行一定偏移,可以结合第一个问题的解决方案进行处理实现。

方法二

感觉是解决多个modal显示位置不对之类的异常
原文链接:BootStrap同时显示多个Modal解决方案

// 通过该方法来为每次弹出的模态框设置最新的zIndex值,从而使最新的modal显示在最前面
$('.modal').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);
});
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值