LLwanran / front_end_studying

前端知识要点
https://llwanran.github.io/front_end_studying/
2 stars 1 forks source link

display:none、visibility:hidden、opacity:0 的区别及适用场景(广州凡科互动一面) #7

Open LLwanran opened 5 years ago

LLwanran commented 5 years ago

本题考察的重点 - 是否理解浏览器的回流与重绘 (Reflow & Repaint),联系昨天文中提到的“切换模式、开关机的时候会概率出现闪屏”的问题:

  1. 浏览器使用流式布局模型 (Flow Based Layout)
  2. 浏览器会把HTML解析成DOM,把CSS解析成CSSOMDOMCSSOM合并就产生了Render Tree
  3. 有了Render Tree,我们就知道了所有节点的样式,然后计算他们在页面上的大小和位置,最后把节点绘制到页面上
  4. 由于浏览器使用流式布局,对Render Tree的计算通常只需要遍历一次就可以完成,但table及其内部元素除外,他们可能需要多次计算,通常要花3倍于同等元素的时间,这也是为什么要避免使用table布局的原因之一

一句话:回流必将引起重绘,重绘不一定会引起回流

回流 (Reflow)

Render Tree中部分或全部元素的尺寸、结构、或某些属性发生改变时,浏览器重新渲染部分或全部文档的过程称为回流。

会导致回流的操作:

一些常用且会导致回流的属性和方法:

重绘 (Repaint)

当页面中元素样式的改变并不影响它在文档流中的位置时(例如:colorbackground-colorvisibility等),浏览器会将新样式赋予给元素并重新绘制它,这个过程称为重绘

性能影响

回流比重绘的代价要更高

回到题目:

共同点:它们都能让元素不可见

display: none

  1. DOM 结构:会让元素完全从渲染树中消失,渲染的时候不占据任何空间, 不能点击
  2. 性能:回流操作,性能开销较大
  3. 事件监听:无法进行 DOM 事件监听
  4. 继承:不会被子元素继承,毕竟子类也不会被渲染
  5. 场景:显示出原来这里不存在的结构

visibility: hidden

  1. DOM 结构:不会让元素从渲染树消失,渲染元素继续占据空间,只是内容不可见,不能点击
  2. 性能:重绘操作,比回流操作性能高一些
  3. 事件监听:无法进行 DOM 事件监听
  4. 继承:会被子元素继承,子元素可以通过设置 visibility: visible 来取消隐藏
  5. 场景:显示不会导致页面结构发生变动,不会撑开

opacity: 0

  1. DOM 结构:不会让元素从渲染树消失,渲染元素继续占据空间,只是内容不可见,可以点击
  2. 性能:重建图层,性能较高
  3. 事件监听:可以进行 DOM 事件监听
  4. 继承:会被子元素继承,且子元素并不能通过 opacity: 1 来取消隐藏
  5. 场景:可以跟transition搭配,可以自定义图片上传按钮