Bootstrap模态框导致页面抖动问题
Bootstrap模态框导致页面抖动
简单介绍Bootstrap模态框:
- 模态框(Modal)是覆盖在父窗体上的子窗体。
- 通常,目的是显示来自一个单独的源的内容,可以在不离开父窗体的情况下有一些互动。
- 子窗体可提供信息、交互等。
学习bootstrap模态框可以去:
模态框导致的页面抖动问题说明:
模态框导致页面抖动的本质是页面的位置发生了位移,这种位移可能是双向的,也可能是单向的。
说到这里我提两个词语解释一下,以免下面你看了不知道我在说什么。
词语一、单层模态框:顾名思义,单层模态框就是指页面一个单独的模态框,点击按钮打开,点击关闭按钮或页面时模态框消失。
- 这种情况下,模态框发生的位移大多数都是双向的,比如向左位移一定距离,在模态框消失的时候页面又向右位移回归原位。
词语二、多层模态框:多层模态框就是有多个模态框联动,比如点击按钮打开模态框之后,再点击模态框上设置的某个按钮,消失点击的模态框,出现另一个模态框,然后点击某个按钮或页面时关闭模态框。
注意:这中间模态框的层数是不固定的。
- 这种情况下,模态框发生的位移就可能是单向的,每次点击都会导致页面发生偏移,模态框消失不回归原位,下次点击,继续上一次的情况,页面会一直向左偏移,直至页面刷新。
多层模态框这个是我主要要说的问题,多层模态框导致的页面位移会在页面有滚动条时出现。
如果你的页面只有一个模态框,或者说你的页面只占有一屏没有滚动条的出现,那么你就基本上不用担心会出现模态框导致页面位移的情况。
当页面有滚动条,多层模态框导致页面位移时怎么解决呢?此时,我们的解决方案就不只是需要用到css
样式了,还需要配合JavaScript
的操作。
大家可以复制运行一下下面的这段代码,多点几次模态框,观察一下页面位移:
代码无需做任何改变,路径我已经改成网络路径,直接复制运行即可。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
<style>
#dou{
width: 100%;
height: 1000px;
background-color: gray;
}
</style>
</head>
<body>
<button data-toggle="modal" data-target="#myModalMate">感悟或建议</button>
<div id="dou"></div>
<div class="myModalMate modal fade" id="myModalMate" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"
aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
<div class="form-group col-sm-6 col-sm-offset-3">
<label for="number">账号:</label><input type="text" class="form-control" placeholder="请输入账号">
</div>
</div>
<div class="modal-footer">
<button class="btn btn-primary" data-toggle="modal" data-dismiss="modal" data-target="#myModalAdvice">快速匹配</button>
</div>
</div>
</div>
</div>
<div class="myModalAdvice modal fade" id="myModalAdvice" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"
aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
<p>个人感悟</p>
</div>
<div class="modal-footer">
<button class="btn btn-primary" data-dismiss="modal">提交</button>
</div>
</div>
</div>
</div>
</body>
<script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
</html>
运行了代码,大家就会很明显发现,页面在向右偏移,以16px
为单位依次增加。
原因:
- 页面向右偏移的像素,其实就是你的滚动条的宽度,当页面没有滚动条时,也基本上不会出现偏移。
- 然后看控制台的元素对
body
的影响:- 当第一个模态框打开时,页面偏移了一个滚动条的宽度即
padding-left:16px
。 - 单击快速匹配时,第一个模态框消失,同时第二个模态框出现,
padding-left:16px
样式也消失。 - 点击提交,第二个模态框也消失,但是此时
padding-left:16px
却再次增加到了body
样式里。
- 当第一个模态框打开时,页面偏移了一个滚动条的宽度即
问题就在这,好像模态框没有按照规则来,没有执行:增加->消失->增加->消失的操作,而是按照:增加->消失->增加的操作后就完结了。
解决方案
单层模态框
如果你是单层模态框的问题,我推荐你去看一篇文章Bootstrap中模态框(modal)出现时页面抖动情况的解决方法,里面对单层模态框导致问题的原因,以及解决方案都有着很详细的介绍。
多层模态框
怎么解决呢?首先我们要解决样式即最后增加的padding-left:16px
,这是罪魁祸首,解决方法就是加上几行代码:
<script>
//.myModalAdvice是我给模态框设置的class,选中的是最后一个模态框,代码里有。
$(".myModalAdvice").on('hidden.bs.modal',function(){
$('body').removeAttr('style class');
});
</script>
可以看到我用了
hidden.bs.modal
,这个属性的意思就是当弹出的模态框消失的时候,执行的回调函数。
我直接设置了当最后一个模态框消失时,直接清除残留的style
和class
,这样页面就不会再最后在加上一个padding-left:16px
的样式,进而也就不会发生页面位移。
但是此时我们又会发现,页面虽然不动了,但是模态框好像抖起来了,原因还是在滚动条上:
- 当我们加上了上面的JavaScript代码之后,会发现,当第一次出现模态框时,本来有的滚动条消失了。
- 当第二个模态框弹出时,模态框的偏移消失,想要回归原位,但是好巧不巧,滚动条又回来了,模态框不得已还得向右偏移,但不是通过模态框自己设置的
padding-left:16px
来进行的,而是被挤的,这就直接造成了模态框的抖动。 - 并且打开第一个模态框时没有滚动条也很难看,因为模态框的遮罩是半透明的,会感觉页面空了一列。
解决这个问题我们还需要在css里写上一行代码:
<style>
/* .modal是我给第一个模态框设置的clss */
.modal-open .modal{
overflow-x: hidden;
overflow-y: scroll;
}
</style>
我解释一下.modal-open
,这个样式想必大家也发现了:
- 当模态框打开时,会自动加上这个样式。我们的滚动条也是在模态框打开时消失的,所以我们需要在第一个模态框打开时选中第一个模态框并设置样式——加上滚动条。
- 如果直接选中第一个模态框,而不写
.modal-open
,就会没有效果,因为不加时,css
样式直接执行了,写上了.modal-open
,样式就不会执行,因为模态框不打开,就找不到属于.modal-open .modal
这种层级关系的模态框。
再说一下这两行样式什么意思:
- 首先
overflow
这个属性:定义溢出元素内容区的内容会如何处理。 - 如果值为
scroll
,不论是否需要,用户代理都会提供一种滚动机制。因此,有可能即使元素框中可以放下所有内容也会出现滚动条 。 - 相应的,
overflow-x
和overflow-y
对应的是X轴和Y轴
也就是说我们设置了模态框打开时,纵向滚动条出现,横向滚动条隐藏,这样就解决了第一个模态框打开时滚动条消失的bug。
如此操作,多层模态框导致的问题就完美解决了。
以上就是多层模态框导致页面抖动的解决方案了,希望可以帮助到你。