您的位置:首页 > 运维架构

关于opacity:0、visibility:hidden、display:none三个属性的比较以及拓展

2018-03-04 13:50 489 查看
今天上午看某头条的时候有个刚入门的前端小伙伴提问道opacity:0、visibility:hidden、display:none。这三个属性的区别,这三个属性在我们日常开发中也算是用到频率也是蛮多的,所以干脆就就把这三个属性放在一起,配合实例做一个比较。
首先这三个属性依次设置为0/hidden/none都可以使得用户看不见页面上的元素,不过他们之间还是有区别的,不然若是一样的话,也就没必要用三个属性值去实现一个一样的效果了。
看一个例子,如下代码所示:
code:<style>
.box{
width: 200px;
height: 50px;
background: greenyellow;
margin:20px;
}
.box1{
opacity: 0;
}
.box2{
visibility: hidden;
}
.box3{
display: none;
}
</style>
<body>
<div class="box box">我是一个正常的盒子</div>
<div class="box box1">我的opacity设置了0 click me</div>
<div class="box box2">我的visibility设置了hidden click me</div>
<div class="box box3">我的display设置了none click me</div>
</body>
    
<script type="text/javascript">

$('.box').click(function () {
console.log($(this).text())
})

</script>


这是一段很简单的demo,分别设置了四个盒子,第一个盒子是正常的,第二个设置了透明度是0,第三个设置了visibility:hidden的属性,第三个设置了display:nono的属性,然后在这三个盒子中分别注册了一个简单的点击事件,点各自的盒子的时候回分别打印出各自的文本内容。
然后我们分别看下各个盒子在浏览器中是怎么显示的:
首先看透明度是0的盒子,如下图所示:



我们可以看到,选中这个节点的时候,在页面上这个元素是有位置的,也就是说他其实是在页面上展示的,不过因为我们设置了透明度是0,使得我们人肉眼看不清而已,但是他是在页面上的,那我们再看看在他上面注册的点击事件是否有效呢。?我们在页面上点击一下这个盒子所在的区域,看看是否会有反应,结果如下:



可以发现,虽然我们肉眼看不见,但是在他上面注册的事件还是有效的,其实这个盒子和其余的盒子没什么不一样,仅仅是因为设置了透明度,所以我们肉眼看不见而已,但也仅此而已。可以理解为“看不见,摸得着”

下面我们再来看下visibility:hidden的盒子怎么样。
首先看在页面上是否占有位置:



可以看到,当我们在dom结构中选择了这个dom节点的时候,在页面上也是占有位置的,就这点而言和opcity:0的表现是一样的。
那么我们在看看点击这个元素所在的区域,是否会触发我们所注册的点击事件呢。?经过测试我们发现,无论怎么点击这个元素在页面所在的区域,都无法触发在他身上注册的事件,这一点和opacity:0表现的就不一样了。我们可以理解为“看不见,摸不着”

下面在看下display:nono的这个元素是如何的:





可以看到我们在dom结构中选中了这个元素,但是在页面上却完全没有显示,这表明,设置了display:none的元素在页面上是根本不存在的。在页面上都没存在,那就更别说会触发点击事件了。
针对display:none这个属性,我也在别的大神的帖子中看到关于这个属性在加载上面的一些扩展,大致意思是,设置了display:none的属性,浏览器就不会加载。直到display改变为非none的时候,才会被加载进来。
原文如下:
想了一下关于他的一个加载问题。
有属性display:none;的结构在加载页面时,是否会同时加载呢?或则是当他变成display:block;的时候才加载的呢?
有属性visibility:hidden;   的结构在加载页面时,是否会同时加载呢?或则是当他变成visibility:visible;   的时候才加载的呢?

个人的看法是:
display:;当他的值变成block 的时候,它所在的结构才会被加载进来。
而visibility就会在加载页面的同时就已经把它加载进来了,因为他的值为hidden的时候,它所占的空间还在。
上文是一段别的大神的观点,一开始我也认为可能是这样的,不过后来细想一下,觉得不应该是这样的。下面是我自己的一些看法,仅供大家参考。
我觉得不管设置了什么样式,他们都会被加载进来。因为我的css,和html加载是分开的这也是所谓的结构和表现是分离的,css是表现,html是结构。在加载css样式的时候并不会说是浏览器要把加载进来的css样式都解析完之后在去加载dom树的,实际浏览器会从html文件进行一个自上而下的加载,并在加载的过程中,进行解析和渲染。渲染一个页面的过程中只会在遇到script标签中js的时候,会加载并执行(没有defer, async属性)完里面的js,解析完js之后继续加载后面的内容,但是css并不会去解析,只会加载,加载完css文件之后会生成一个cssom(css object model)然后会和dom树得到一个渲染树即render树,来渲染元素结构的表现形式:
大致过程如下:
解析html来构建dom树 -> 构建render树->布局render树(layout)->绘制render树(painting)。
css文件异步加载完之后会生成cssom(css object model),然后dom树结合cssom来生成render树的,生成render市之后就是layout环节,将所有节点的位置计算出来,也就是我们所了解的重排过程,最后通过painting环节将所有节点展现在显示器上,即重绘。当然,这里面很多其他细节,这儿只是粗糙的讲一下大概,不然我们就跑题了。当然每个浏览器的渲染过程都不会完全一样,以上只是个人理解的大概流程。
所以我认为不管给元素结构设置成了什么属性,他都会被浏览器加载进来的。

9c80
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: