2017-12

博客分类: 江河计划-月总结

2017-12

算法

插半优化

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;
}

希尔排序

var arr = [4,2,3,2,3,5,1,0,7,6];
Array.prototype.shellSort = function(){
    var len = this.length,
        temp,
        gap = 1;
    while(gap < len/3){
        gap = gap * 3 + 1;
    }
    for(gap; gap > 0; gap = parseInt(gap / 3, 10)){
        for(var i=gap; i<len; i++){
            var temp = this[i];
            for(var j=i-gap; j>=0 && this[j] > temp; j-=gap){
                this[j+gap] = this[j];
            }
            this[j+gap] = temp;
        }
    }
    return this;
}

归并排序

var arr = [4,2,3,2,3,5,1,0,7,6];
Array.prototype.mergeSortRec = function(){
    if (this.length === 1) return this;
    var mid = parseInt(this.length / 2),
        left = this.slice(0, mid),
        right = this.slice(mid);
    return this.merge(left.mergeSortRec(), right.mergeSortRec());
}

Array.prototype.merge = function(left, right){
    var il = 0,
        ir = 0,
        result = [];
    while(il < left.length && ir < right.length){
        if(left[il] < right[ir]){
            result.push(left[il++])
        }else{
            result.push(right[ir++])
        }
    }
    while(il < left.length){
        result.push(left[il++])
    }
    while(ir < right.length){
        result.push(right[ir++])
    }
    return result
}

class Stack {
    private items: any[] = [];
    push(...elements: any[]) {
        this.items = this.items.concat(elements)
    }
    pop() {
        return this.items.pop();
    }
    peek() {
        return this.items.length;
    }
    isEmpty(): boolean {
        return this.items.length === 0;
    }
    clear() {
        this.items = [];
    }
    size(): number {
        return this.items.length;
    }
    print(): string {
        return this.items.toString();
    }
}

正则

千分位:

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

获取 version 号:/[^_]*(?=\.)/

舍去两位小数之后:replace(/(^\d*\.\d{2})(\d*)/, '$1')

时分秒:/((^[0|1]\d)|(^2[0-3])):[0-5]\d:[0-5]\d$/

知识整理

浏览器渲染

浏览器的主要组件包括:

  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技术,这是一种轻量级完整的客户端存储技术

渲染概念:

  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 解析和渲染延迟。

渲染优化

传送门

DOMReady

首先看 script 标签渲染

  1. <script src="script.js"></script>没有 defer 或 async,浏览器会立即加载并执行指定的脚本,“立即”指的是在渲染该 script 标签之下的文档元素之前,也就是说不等待后续载入的文档元素,读到就加载并执行。
  2. <script async src="script.js"></script>有 async,加载和渲染后续文档元素的过程将和 script.js 的加载与执行并行进行(异步)。
  3. <script defer src="myscript.js"></script>有 defer,但是 script.js 的执行要在所有元素解析完成之后,DOMContentLoaded 事件触发之前完成。

DOMContentLoaded

当初始html文档完全加载并解析之后触发,无需等待样式、图片、子frame结束。

// 使用方法
document.addEventListener("DOMContentLoaded", function (event) {
    console.log("初始DOM 加载并解析");
});

load

当一个资源及其依赖的资源结束加载时触发。包括页面中的样式、图片、子frame等;

// 使用方法
window.addEventListener("load", function (event) {
    console.log("window 所有资源加载完成");
});

readystatechange

documentreadyState属性来描述documentloading状态,readyState的改变会触发readystatechange事件。

  1. loading:文档仍然在加载
  2. interactive:文档结束加载并且被解析,但是想图片,样式,frame之类的子资源仍在加载
  3. complete:文档和子资源已经结束加载,该状态表明将要触发load事件。
    document.onreadystatechange = function () {
        console.log(document.readyState)
        if (document.readyState === "complete") {
            console.log('初始DOM,加载解析完成')
        }
    }

beforeunload

当浏览器窗口,文档或其资源将要卸载时,会触发beforeunload事件。这个时候文档是依然可见的,并且这个事件在这一刻是可以取消的。 如果处理函数为Event对象的returnValue属性赋值非空字符串,浏览器会弹出一个对话框,来询问用户是否确定要离开当前页面(如下示例)。有些浏览器会将返回的字符串展示在弹框里,但有些其他浏览器只展示它们自定义的信息。没有赋值时,该事件不做任何响应。

window.addEventListener("beforeunload", function (event) {
    console.log('即将关闭')
    event.returnValue = "确定要退出么?";
});

unload

当文档或者一个子资源将要被卸载时,在beforeunload 、pagehide两个事件之后触发。 文档会处于一个特定状态。

页面加载流程

  1. 第一个readyState肯定接收不到,DOM 开始加载。
  2. document 加载结束,但是样式、图片等资源并未结束,此时触发readystatechange,状态变为readyState === 'interactive'触发事件DOMContentLoaded
  3. 等资源加载完毕时触发readystatechange,状态变为readyState === 'complete',触发load事件。
  4. 关闭页面时一次触发beforeunloadunload

DOM 基础

nodeType

可能产生的值如下:

// IE 下无效
if(node.nodeType == Node.ELEMENT_NODE)

// 任何浏览器下都有效
if(node.nodeType == 1)

节点间的关系

image

操作节点

查询节点

属性操作

注:node.attributes是一个类数组,会有一堆方法获取属性的节点,

DOM 扩展

选择符

元素遍历

类名操作

element.classList返回数组,是该节点的类名

自定义数据属性

data-xxx在 dom 节点存放数据,使用element.dataset获取存放在dom上的数据

插入节点

让节点出现到视窗

子节点获取与检测