zoukankan      html  css  js  c++  java
  • JS的DOM操作

    摘要

     想稍微系统的说说对于DOM的操作,把Javascript和jQuery常用操作DOM的内容归纳成思维导图方便阅读,同时加入性能上的一些问题.

    前言

     在前端开发的过程中,javascript极为重要的一个功能就是对DOM对象的操作,无论增删改查在前端页面操作这一范围内都是比较消耗性能的.如何高效率的,便捷的操作DOM,这就是本文要讲述的.希望看完全文,你能知道如何更高效的通过原生js以及jQuery操作DOM元素.

    操作DOM

    这里我希望介绍的相对系统一点,而不是东一句西一句,所以把Javascript和jQuery常用操作DOM的内容归纳成思维导图方便阅读.这里就总结出最基本最常用的DOM操作.

     Javascript:

    jQuery:

    上面的思维导图分别是javascript和jQuery下操作DOM的一些常用Function,并不完全我仅仅列出相对常用的.这里我比较推荐的是jQuery的操作方式,更加便捷的同时在性能上也相对有所保障.

    性能影响

         DOM操作会导致最重要的,也是我们最需要的问题就是导致用户阻塞的重构(reflow)和重绘(repaint).比较通俗的一句话就是你在页面上的任何操作都是有代价的,有些大有些小,如果我们的操作比较频繁或者波及范围较大,那么就要讲究方式和技巧.reflow和repaint就是我们在改变页面或者说操作DOM时,会带来的两种后果.

        reflow意味着结构的改变,比如一堆元素堆叠,改变其中一个的宽高,那么相应的所有元素的位置都要改变.repaint意味着样式的改变比如div调整了背景色等,但是位置不变,只改变我们操作的元素.所以通常来看repaint的代价要远小于reflow,速度也更快.

        影响性能的因素我们已经知道了,那么下面看一下怎么避免.

        更有效的操作

        最重要的观点:既然任何DOM操作都有代价,那么最好就是不操作或者最少的操作DOM.所以首先记住一个原则,将DOM操作尽量少!这里有我认为主要的4个原则,记下来足以应付大多数情况.

      (1) 能放到DOM操作之外的操作就放到外面,DOM操作要尽量少.

    DOM操作优化中这一观点在网上已经很普及了,很多例子都有比如遍历一个数组然后逐渐把内容添加到DOM上,这里就推荐先遍历完数组,然后一次性在DOM上操作.大家可以看代码:

    // 不好的做法
    for (var i=0; i < items.length; i++){
        var item = document.createElement("li");
        item.appendChild(document.createTextNode("Option " + i));
        list.appendChild(item);
    }   
     
     
    // 更好的做法
    // 使用容器存放临时变更, 最后再一次性更新DOM
    var fragment = document.createDocumentFragment();
    for (var i=0; i < items.length; i++){
        var item = document.createElement("li");
        item.appendChild(document.createTextNode("Option " + i));
        fragment.appendChild(item);
    }
    list.appendChild(fragment);

        (2) 大范围操作先把容器隐藏,在其中操作完成后,再显示.

        这是一个我刚接触前端时遇到的一个优化办法,当时很不理解为什么display=none之后操作就算是性能优化了.但是数据证明如此渲染确实快了很多,这个的原理要涉及到浏览器加载和渲染的原理,简单说就是隐藏的元素其中不会产生reflow.这个例子我就不写了,很简单.

        (3) 样式操作不要注意修改属性,直接替换class

        这个还是比较容易理解的,你逐一修改要访问很多次,而替换class就相当于批量操作了,访问一次DOM就可以了,当然性能提高了.

        (4) 用变量保存DOM对象而不是多次获取,同时减少操作DOM属性的次数.

    //不好
     
    function addAnchor(parentElement, anchorText, anchorClass) {
      var element = document.createElement('a');
      parentElement.appendChild(element);
      element.innerHTML = anchorText;
      element.className = anchorClass;
    }
     
     
    //更好
     
    function addAnchor(parentElement, anchorText, anchorClass) {
      var element = document.createElement('a');
      element.innerHTML = anchorText;
      element.className = anchorClass;
      parentElement.appendChild(element);
    }

    总结

        说到这里DOM的操作就差不多了,其实没有什么太新鲜的内容只是做了一个系统点总结.对于性能这部分要平时积累这个意识,因为大多数时候它在开发过程中体现的并不明显.本文还有很多不足,希望大家留言沟通吧.

    注:第四点中两种方式执行过程的不同之处

    例如:如果想想加入一个a标签,标签有class和内容.如果第一种方式,你是先将节点加入到DOM树中然后添加内容和class,就是一个先reflow再repaint的过程.如果你先为节点在DOM对象变量的状态下就加好class和内容,再appendChild,就只有一个reflow的过程.自然性能更好.

    转载地址:http://my.oschina.net/blogshi/blog/198910?fromerr=j73U61KS

  • 相关阅读:
    HDU 2433 Travel (最短路,BFS,变形)
    HDU 2544 最短路 (最短路,spfa)
    HDU 2063 过山车 (最大匹配,匈牙利算法)
    HDU 1150 Machine Schedule (最小覆盖,匈牙利算法)
    290 Word Pattern 单词模式
    289 Game of Life 生命的游戏
    287 Find the Duplicate Number 寻找重复数
    283 Move Zeroes 移动零
    282 Expression Add Operators 给表达式添加运算符
    279 Perfect Squares 完美平方数
  • 原文地址:https://www.cnblogs.com/moqiutao/p/5075009.html
Copyright © 2011-2022 走看看