• 浏览器是如何工作的系列:页面布局


    布局(Layout/Reflow):

    当渲染对象被创建并添加到树中,它们并没有位置和大小,计算这些值的过程称为layout或reflow。
    Html使用基于流的布局模型,意味着大部分时间,可以以单一的途径进行几何计算。流中靠后的元素并不会影响前面元素的几何特性,所以布局可以在文档中从右向左、自上而下的进行。也存在一些例外,比如html tables。 坐标系统相对于根frame,使用top和left坐标。
    布局是一个递归的过程,由根渲染对象开始,它对应html文档元素,逐级递归,为每个渲染对象计算需要的几何信息。根渲染对象的位置是0,0,它的大小是viewport-浏览器窗口的可见部分。
    所有的渲染对象都有一个layout或reflow方法,同时每个渲染对象调用需要布局的children的layout方法。

    1.Dirty bit 系统

    为了不因为每个小变化都全部重新布局,浏览器使用一个Dirty bit系统,一个渲染对象发生了变化或是被添加了,就标记它及它的子节点为dirty——需要layout。
    存在两个标识:“dirty”和“children are dirty”,"children are dirty"说明即使这个渲染对象已经渲染完了,但是它的孩子节点还需要一个layout.

    2.全局和增量Layout

    在整棵渲染树触发Layout时,称为全局Layout,这可能在下面这些情况下发生:
    a>一个全局样式的改变,影响所有渲染对象,例如font-size的改变
    b>窗口缩放
    Layout也可以是增量的,这样只有标志为dirty的渲染对象会重新布局(也将导致一些额外的布局)。增量 Layout会在渲染对象dirty时异步触发,例如,当网络接收到新的内容并添加到Dom树后,新的渲染对象会添加到渲染树中。如下图5.1


    3.异步和同步Layout

    增量layout的过程是异步的,Firefox为增量layout生成了reflow队列,以及一个调度执行这些批处理命令。Webkit也有一个计时器用来执行增量layout-遍历树,为dirty状态的渲染对象重新布局。
    另外,当脚本请求样式信息时,例如“offsetHeight”,会同步的触发增量布局。
    全局的layout一般都是同步触发。
    有些时候,layout会被作为一个初始layout之后的回调,比如滚动条的滚动。

    4.优化

    当一个layout因为resize或是渲染位置改变(并不是大小改变)而触发时,渲染对象的大小将会从缓存中读取,而不会重新计算。
    一般情况下,如果只有子树发生改变,则layout并不从根开始。这种情况发生在元素自身并且不影响它周围元素,例如,将文本插入文本域(否则,每次击键都将触发从根开始的重排)。

    5.Layout过程

    Layout 通常有以下几个部分:
    a>parent 渲染对象决定它自己的宽度
    b>parent 渲染对象读取children
    1)设置children渲染对象(设置它的x和y)
    2)在需要时(它们当前为dirty或是处于全局layout或者其他原因)调用child渲染对象的Layout,并计算child的高度
    3)parent渲染对象使用child渲染对象的累积高度,以及margin和padding的高度来设置自己的高度-这将被

    parent渲染对象的parent使用,即通过child高度来定义parent高度。
    4)将dirty标识设置为false
    Firefox使用一个“state”对象(nsHTMLReflowState)做为参数去布局(firefox称为reflow),state包含

    parent的宽度及其他内容。
    Firefox布局的输出是一个“metrics”对象(nsHTMLReflowMetrics)。它包括渲染对象计算出的高度。

    6.宽度的计算

    渲染对象的宽度使用容器的宽度、渲染对象样式中的宽度及margin、border进行计算。例如,下面这个div的

    宽度:<div style="50%"></div>
    ebkit中宽度的计算过程是(RenderBox类的calcWidth方法):
    a>容器的宽度是容器的可用宽度和0中的最大值,这里的可用宽度为:contentWidth=clientWidth()-

    paddingLeft()-paddingRight(),clientWidth和clientHeight代表一个对象内部的不包括border和滑动条的

    大小
    b>元素的宽度指样式属性width的值,它可以通过计算容器的百分比得到一个绝对值,加上水平方向上的

    border和padding。到这里是最佳宽度的计算过程,现在计算宽度的最大值和最小值,如果最佳宽度大于最大

    宽度则使用最大宽度,如果小于最小宽度则使用最小宽度。最后缓存这个值,当需要layout但宽度未改变时

    使用。

    7.折行

    当一个渲染对象在布局过程中需要折行时,则暂停并告诉它的parent它需要折行,parent将创建额外的渲染对象并调用它们的layout。

  • 相关阅读:
    [转]document对象execCommand的命令参数介绍
    Windows蓝屏说明
    PHP手册下载
    编写简单的代码生成工具
    EXCEL中标记两列中都存在的数据,过滤B列中存在A列中不存在的数据[原创]
    SC Create 添加服务不成功(总弹帮助信息)的原因[转]
    Excel中删除两列中重复的数据[原创]
    禁止更改桌面背景及活动桌面的批处理_最终版[原创]
    EXCEL中自动检测当前单元格或上一单元格在列A中是否存在相同数据[原创]
    EXCEL中避免同一列及相邻列中出现重复数据[原创]
  • 原文地址:https://www.cnblogs.com/suncoolcat/p/3313315.html
Copyright © 2020-2023  润新知