zoukankan      html  css  js  c++  java
  • 一些JavaScript中的DOM的优化小技巧

    在进行DOM优化时需要关注的问题有:修改DOM的时候,会引起页面的重排,重绘。因为JS是单线程执行的,那么在重排重绘的过程中可能会阻塞用户的操作。为了更好的用户体验,必须要严格控制这些操作。


    一、对象集合 NodeList
    当我们调用:getElementsByTagName,getElementsByName,getElementsByClassName的时候,返回的结果是一个NodeList,这个NodeList是实时的。如果你修改对应的html,那么NodeList中也会得到修改。
    而且,NodeList的length属性是指访问NodeList的那一刻,其中包含的节点数量。
    所以当下面这个代码运行时有可能会导致死循环(这里先不讨论在一个循环里多次调用appendChild方法):
    1 var divList = document.getElementsByTagName("div");
    2 for( var i = 0; i < divList.length ; i++ ){
    3     var d = document.createElement("div");
    4     document.body.appendChild(d);
    5     console.log(i);
    6 }
    因为当i增加的时候,divList.length也一直在以相同的速度增加,所以当文档中原本的<div>的数量 大于等于 1时,i永远不可能等于divList.length。运行代码的时候,你的页面甚至有可能会显示不出这些div,但是你可以通过控制台打印i的值观察其执行的次数。
    所以,永远不要写这样的代码,但是你可以像下面这样子写:
    1 var divList = document.getElementsByTagName("div");
    2 for( var i = 0, len = divList.length ; i < len ; i++ ){
    3     var d = document.createElement("div");
    4     document.body.appendChild(d);
    5     console.log(i);
    6 }
    我们还可以通过一些方法将NodeList转换成普通数组,然后在对其进行操作:
    var arrayOfNodes = Array.prototype.slice.call(divList,0);
    但是这个方法在IE8及IE之前的版本无效,因为IE8之前将NodeList实现为COM对象,如果真的需要大量用到这个NodeList,并且在IE8和IE之前版本中,那么只好遍历了。
     
    二、对DOM进行一些样式的修改
    当修改元素的CSS属性时,如果涉及到很多CSS属性,那么不妨考虑增加一个CSS class,然后通过改变元素节点的class来实现这个目的。
    修改前:
    1 element.style.cssText += "200px;height:200px;background-color:red;border:1px solid white";
    修改后:
    在css文件中增加一个样式:
    1 .active{
    2     width:200px;
    3     height:200px;
    4     background-color:red;
    5     border:1px solid white;
    6 }
    在JS中这样写:
    1 element.className += " active"
     
    三、节点增加、移除
    比如在一个文档中有一些比较复杂的DOM树需要进行大量的渲染操作,那我们可以先设置其隐藏,让其脱离文档流,等到相应的改变做完之后,再将其显示,使其加入到文档流中。这样做的好处是不会在页面上出现“运行一点,渲染一点”的情况,而是“先运行全部”,“再渲染全部”,从而提高了效率。
     
    最后对于上面曾提到的:多次调用appendChild方法导致的多次重排,重绘。可以通过:document.createDocumentFragment()解决这个问题:
    1 var divList = document.getElementsByTagName("div"),
    2     tempFragment = document.createDocumentFragment();
    3 for( var i = 0; i < 100 ; i++ ){
    4     var d = document.createElement("div");
    5     d.className += " active"
    6     tempFragment.appendChild(d);
    7 }
    8 document.body.appendChild(tempFragment);
     


    更多内容参考:《高性能JavaScript一书》

  • 相关阅读:
    WCF 第十一章 工作流服务 处理上下文
    WCF 第十一章 工作流服务 总结
    如何: 连接到一台远程计算机(下)
    WCF 第十一章 工作流服务 从WF暴露一个服务(中)
    WCF 第十一章 工作流服务 从WF暴露一个服务(下)
    WCF 第十一章 工作流服务 从WF暴露一个服务
    [转载]不太规则的迷宫生成算法1
    c# 文件操作
    一些重要的算法
    十个开源的Javascript框架
  • 原文地址:https://www.cnblogs.com/iceseal/p/3881182.html
Copyright © 2011-2022 走看看