8.DOM和浏览器模式——JavaScript模式学习笔记
2019-03-08 本文已影响0人
小二子SAMA
一、DOM
1.DOM访问
DOM是独立于JavaScript引擎而实现的,对DOM的访问,是制约JS性能的主要瓶颈。因此,因该尽量减少DOM操作:
1)避免在循环中使用DOM访问;
2)将DOM引用分配给局部变量,并且使用这些局部变量,而不是每次都重新获取DOM引用;
3)在可能的情况下使用selector API,使用CSS选择器字符串作为参数,返回一个匹配该选择的DOM结点列表。
document.getElementById()是最简单快捷的查找结点的方法,所以最好为经常访问的元素增加id属性。
var selectedEle = document.querySelector("ul .selected");
var classEle = document.querySelectorAll("#widget .class");
2.操纵DOM
对DOM元素的增删会导致页面的重排和重绘,非常耗时,所以应该尽量避免更新DOM元素,对不可避免的DOM操作,最好使用文档碎片(document fragment)技术来进行DOM操作批量处理。
//直接操作DOM和使用document.fragment对比试验
var p , t, max = 100000;
var startTime = new Date().getTime();
// 直接操作DOM 640ms
for(var i = 0; i < max; i++) {
p = document.createElement('p');
t = document.createTextNode(i);
p.appendChild(t);
document.body.appendChild(p);
}
//通过fragemnt,最后一次性DOM 348ms
var fragment = document.createDocumentFragment();
for(var i = 0; i < max; i++) {
p = document.createElement('p');
t = document.createTextNode(i);
p.appendChild(t);
fragment.appendChild(p);
}
document.body.appendChild(fragment);
var endTime = new Date().getTime();
console.log(endTime - startTime);
当需要更新DOM树时,可以将需要更新的子树进行克隆,对克隆镜像进行修改操作,最后用克隆镜像替换原来的子树。
// 更新
var oldNode = document.getElementById('result');
clone = oldNode.cloneNode(true);
// 处理操作对象...
oldNode.parentNode.replaceChild(clone, oldNode);
二、事件
1.定义跨浏览器事件监听器
var b = document.getElementById('clickme');
if (document.addEventListener) {
// 第三个函数表示是否在捕获阶段调用事件处理程序
b.addEventListener('click', myHandler, false);
} else if (document.attachEvent) {
b.attachEvent('onclick', myHandler);
} else {
b.onclick = myHandler;
}
- 事件处理程序定义及解析
function myHandler(e) {
var src, parts;
// 获取事件和源元素
e = e || window.event;
src = e.target || e.srcElement;
// 功能实现...
// 取消事件冒泡
if (typeof e.stopPropagation === 'function') {
e.stopPropagation();
}
if (typeof e.cancelBubble !== 'undefined') {
e.cancelBubble = true;
}
// 阻止执行默认操作
if (typeof e.preventDefault === 'function') {
e.preventDefault();
}
if (typeof e.returnValue !== 'undefined') {
e.returnValue = false;
}
}
3.事件授权
结合事件冒泡,减少为每个节点附加的时间监听器数量。将事件监听器附加在所有要监听的元素的父元素上,在功能实现部分,对源元素的类型(或者类、id)进行判断,实现相同的效果。
与addEventListener结合的实现方式:
// 对所有li进行click事件监听
window.onload=function(){
var ulNode=document.getElementById("list");
ulNode.addEventListener('click',function(e){
if(e.target&&e.target.nodeName.toUpperCase()=="LI"){/*判断目标事件是否为li*/
alert(e.target.innerHTML);
}
},false);
};