DOM编程

一、DOM操作慢的本质原因
文档对象模型(DOM)是一个与语言无关的,用于操作XML和HTML文档的应用程序接口。DOM在浏览器中的接口是用JavaScript实现的。浏览器通常会把DOM和JavaScript独立实现。
(1)在IE中,JavaScript的实现名为JScript,位于jscript.dll文件中;DOM的实现则存在另一个库中,名为mshtml.dll(内部叫Trident),UA头:
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)
(2)在chrome中,JavaScript引擎叫V8,渲染引擎是WebKit中的WebCore,UA头:
User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36
(3)在firefox中,JavaScript引擎叫SpiderMonkey,渲染引擎为Gecko,UA头:
 User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:28.0) Gecko/20100101 Firefox/28.0
 
可以把DOM和JavaScript想象成两个岛屿,把接口想象成链接岛屿的桥梁,ECMAScript每次访问DOM都需要交过桥费。访问次数越多费用越高。因此,尽量减少DOM操作对性能的提升有很大帮助。
 
二、修改页面区域通常有两种方式:
innerHTML,非标准但各浏览器支持较好。
标准的DOM API:document.createElement
两种方式性能相差无几。
 
三、昂贵的HTML集合
document.getElementsByName
document.getElementsByClassName
document.getElementsByTagName
返回HTML集合,类数组对象。有length属性(没有push,slice),可循环遍历。但是每次读取length属性或者通过下标访问元素都会重复查询,获取最新的信息。在迭代HTML集合的过程中一定要注意:
局部变量保存length属性,如果需要重复访问集合中的同一个元素,也要用局部变量保存。避免重复查询。
 
三、DOM遍历
DOM属性:childNodes,firstNode,lastNode,nextSibling,prevSibing是不区分元素节点,注释节点和文本节点的,但是许多现代浏览器实现的DOM API是只返回元素节点的,使我们可以在程序中省去nodeType的判断过程。

children

childNodes

childElementCount

childNodes.length

firstElenmentChild

firstChild

lastElementChild

lastChild

nextElementSibling

nextSibling

previousElementSibling

previousSibling

IE678只支持children属性。

四、类选择器

类选择器(返回的是NodeList也是类数组结构,与HTML集合不同的是,NodeList是静态列表)

document.querySelectorAll("#menu a") 等价于将 document.getElementById("menu").getElementsByTagName('a')的结果拷贝到数组中。

document.querySelectorAll("div.waring,div.notice") 同时返回含class为'waring'或者'notice'的元素

五、重排与重绘

浏览器下载完所有的组件后会生成两种内部数据结构:

DOM树,表示页面结构

渲染树,表示DOM节点如何显示

DOM树中的每一个非隐藏节点在渲染树中至少存在一个对应的节点,渲染树中的节点称为“帧”

当DOM树中的元素几何属性(宽和高)发生了变化,其他元素的几何属性也有可能受到影响,浏览器会使渲染树中受到影响的部分失效,重新构造渲染树,这个过程叫做“重排(reflow)”,有的书上也称为“回流”。完成重排后,浏览器会重新绘制受到影响的部分到屏幕中,该过程称为“重绘(repaint)”

并不是所有的DOM变化都会改变几何属性,比如改变背景色。

六、发生重排的情况:

添加或者删除可见元素

元素位置发生变化

元素尺寸发生变化(宽高边框)

内容改变

页面渲染器初始化

浏览器窗口尺寸变化

七、减少重排重绘的方法:

修改样式,一次性修改所有样式:el.style.cssText = 'border-left:1px;border-right:1px'

不要这样:el.style.borderLeft = '';el.style.borderRight='';

批量插入DOM。拼装好html后一次性插入innerHTML,不要循环插入。也可使用文档片段DocumentFragment一次性插入。

八、IE和:hover

如果有大量元素使用hover,会降低响应速度。IE8中比较明显。

九、事件委托

DOM标准定义的事件必须经历的三个阶段:

捕获

到达目标

冒泡

IE不支持捕获,实现事件委托,冒泡已经够了。

如果事件委托绑定的是单击事件,而且目标元素为A标签,需要阻止默认的跳转动作

标准浏览器:

e.preventDefault()

e.stopPropagation()

IE浏览器:

e.returnValue = false;

e.cancelBubble = true;

 
原文地址:https://www.cnblogs.com/hellohuman/p/3852238.html