DOM 相关 - 浏览器渲染

博客分类: 江河计划

DOM 相关 - 浏览器渲染

算法

插入排序

var arr = [4,2,3,2,3,5,1,0,7,6]
Array.prototype.insertSort = function(){
    for(var i=1; i<this.length; i++){
        var j = i,
            tmp = this[i];
        while(j>0 && this[j-1] > tmp){
            this[j] = this[j-1]
            j--;
        }
        if(j !== i){
            this[j] = tmp
        }
    }
    return this;
}

插半优化

var arr = [4,2,3,2,3,5,1,0,7,6]
Array.prototype.insertSort = function(){
    for(var i=1; i<this.length; i++){
        var low = 0,
            high = i - 1;
            temp = this[i];
        while(low <= high){
            var minIndex = parseInt((high + low) / 2, 10);
            if(this[minIndex] === temp){
                low = minIndex;
                break;
            }
            if(this[minIndex] < temp){
                low = minIndex + 1;
            }else{
                high = minIndex - 1;
            }
        }
        if(low === i){
            continue;
        }
        for(var j=i; j>low; j--){
            this[j] = this[j-1];
        }
        this[low] = temp;
    }
    return this;
}

正则

身份证:/^\d{15}$|^\d{17}[\d|x|X]$/

国内座机:/(^\d{3}-\d{8}$)|(^\d{4}-\d{7}$)/

千分位:

function comdify(n){
    return n.replace(/(\d*)(\.(\d)*)/, function(s, s1, s2){
        return s1.replace(/\d{1,3}(?=(\d{3})+$)/g, '$&,') + s2
    })
}

知识整理:浏览器渲染

浏览器的主要组件包括:

  1. 用户界面 (User Interface) - 包括地址栏、后退/前进按钮、书签目录等,也就是你所看到的除了用来显示你所请求页面的主窗口之外的其他部分。
  2. 浏览器引擎 (Browser engine) - 用来查询及操作渲染引擎的接口。
  3. 渲染引擎 (Rendering engine) - 负责解析用户请求的内容(如HTML或XML,渲染引擎会解析HTML或XML,以及相关CSS,然后返回解析后的内容)
  4. 网络(Networking)- 用来完成网络调用,例如http请求,它具有平台无关的接口,可以在不同平台上工作。
  5. UI后端(UI backend) - 用来绘制类似组合选择框及对话框等基本组件,具有不特定于某个平台的通用接口,底层使用操作系统的用户接口。
  6. JS解释器(JavaScript interpreter) - 用来解释执行JS代码。
  7. 数据存储 (Data storage) - 属于持久层,浏览器需要在硬盘中保存类似cookie的各种数据,HTML5定义了web database技术,这是一种轻量级完整的客户端存储技术 image

渲染概念:

  1. DOMTree:浏览器将HTML解析成树形的数据结构。
  2. CSSRuleTree:浏览器将CSS解析成树形的数据结构。
  3. RenderTree: DOM和CSSOM合并后生成Render Tree。
  4. layout: 有了Render Tree,浏览器已经能知道网页中有哪些节点、各个节点的CSS定义以及他们的从属关系,从而去计算出每个节点在屏幕中的位置。
  5. painting: 按照算出来的规则,通过显卡,把内容画到屏幕上。
  6. reflow(回流):当浏览器发现某个部分发生了点变化影响了布局,需要倒回去重新渲染,内行称这个回退的过程叫 reflow。reflow 会从 这个 root frame 开始递归往下,依次计算所有的结点几何尺寸和位置。reflow 几乎是无法避免的。现在界面上流行的一些效果,比如树状目录的折叠、展开(实质上是元素的显 示与隐藏)等,都将引起浏览器的 reflow。鼠标滑过、点击……只要这些行为引起了页面上某些元素的占位面积、定位方式、边距等属性的变化,都会引起它内部、周围甚至整个页面的重新渲 染。通常我们都无法预估浏览器到底会 reflow 哪一部分的代码,它们都彼此相互影响着。
  7. repaint(重绘):改变某个元素的背景色、文字颜色、边框颜色等等不影响它周围或内部布局的属性时,屏幕的一部分要重画,但是元素的几何尺寸没有变。

渲染过程

  1. 浏览器会将 HTML 解析成一个 DOM 树,DOM 树的构建过程是一个深度遍历过程:当前节点的所有子节点都构建好后才会去构建当前节点的下一个兄弟节点。
  2. 将 CSS 解析成 CSS Rule Tree 。
  3. 根据 DOM 树和 CSS Rule Tree 来构造 Rendering Tree。注意:Rendering Tree 渲染树并不等同于 DOM 树,因为一些像 Header 或 display:none 的东西就没必要放在渲染树中了。
  4. 有了 Render Tree,浏览器已经能知道网页中有哪些节点、各个节点的 CSS 定义以及他们的从属关系。下一步操作称之为 layout,顾名思义就是计算出每个节点在屏幕中的位置。
  5. 再下一步就是绘制,即遍历 render 树,并使用 UI 后端层绘制每个节点。

渲染过程中的阻塞

css 的加载并不会导致 html 解析和渲染的停止,但是会影响到 js 脚本的执行。因为 js 脚本不仅可以读取修改到 dom,也可以读取修改到 cssom。故在 js 脚本执行前,browser 必须保证到 css 文件完全加载并解析完成,即 cssom 树完全构建好。这就导致了 js 执行的延迟,也因此导致 html 解析和渲染延迟。

渲染优化

http://www.jianshu.com/p/a32b890c29b1

解决问题

pixi 画图,主要问题是解析一个巨大的 ini 文件,解析文件之后将文件内容画在画布上,解析数据比较繁琐,更多的的是了解文档,做好解析。但是对于画布的拖动和缩放还是一个小难点。

缩放:使用 hammer.js 作为手势库,绑定缩放的事件,设定一个缩放范围,缩放是在原有基础上,并且需要有一个中心点,主要是这个中心点不是很好取,下面是缩放的操作。缩放完成后记录当前的缩放比例。

var scaleNum = ev.scale * scaleBase;
if (scaleNum < 0.5 || scaleNum > 4) {
    return;
}
stage.scale.set(scaleNum, scaleNum);
stage.position.set((scaleNum - 1) * -ev.center.x, (scaleNum - 1) * -ev.center.y);

拖动:对事件 touchstart 和 touchmove 进行绑定,在开始移动时,记录初始位置,移动过程中不断与初始位置对比得到当前移动端距离,将舞台的中心点设置在移动的位置上,这里需要注意的是,边界问题,边界的距离是与缩放比例有关的

if (isScaleing || !moveStartX || !moveStartX) {
    return;
}
var moveX = ev.data.global.x - moveStartX,
    moveY = ev.data.global.y - moveStartY;
text.setText(moveX, moveY);
// 100 为可变参数
if (moveRange.x > 0 && moveX <= 100 / scaleBase && moveX >= -1 * moveRange.x) {
    stage.position.set(moveX, stage.y);
}
if (moveRange.y > 0 && moveY <= 100 / scaleBase && moveY >= -1 * moveRange.y) {
    stage.position.set(stage.x, moveY);
}