欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Bootstrap模态框导致页面抖动问题

程序员文章站 2024-01-10 17:19:43
...

Bootstrap模态框导致页面抖动

简单介绍Bootstrap模态框:

  • 模态框(Modal)是覆盖在父窗体上的子窗体。
  • 通常,目的是显示来自一个单独的源的内容,可以在不离开父窗体的情况下有一些互动。
  • 子窗体可提供信息、交互等。

学习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的影响:
    1. 当第一个模态框打开时,页面偏移了一个滚动条的宽度即padding-left:16px
    2. 单击快速匹配时,第一个模态框消失,同时第二个模态框出现,padding-left:16px样式也消失。
    3. 点击提交,第二个模态框也消失,但是此时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,这个属性的意思就是当弹出的模态框消失的时候,执行的回调函数

我直接设置了当最后一个模态框消失时,直接清除残留的styleclass,这样页面就不会再最后在加上一个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-xoverflow-y对应的是X轴和Y轴

也就是说我们设置了模态框打开时,纵向滚动条出现,横向滚动条隐藏,这样就解决了第一个模态框打开时滚动条消失的bug。

如此操作,多层模态框导致的问题就完美解决了。


以上就是多层模态框导致页面抖动的解决方案了,希望可以帮助到你。