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;
}
  1. 事件处理程序定义及解析
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);
  
};
上一篇下一篇

猜你喜欢

热点阅读