摘要

想稍微系统的说说对于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

JS的DOM操作 - 你真的了解吗?的更多相关文章

  1. JS的DOM操作及动画

    JS的DOM操作DOM:Document Object ModelBOM:Bowers(浏览器) Object Model找到元素:var a=document.getElementById(&quo ...

  2. JS的DOM操作语法

    整理了一下JS的DOM操作语法,这里做下记录. <!DOCTYPE html> <html> <head> <meta charset="utf-8 ...

  3. js的dom操作(整理)(转)

    js的dom操作整理(整理)(转) 一.总结 一句话总结: dom操作有用原生js的dom操作,也可以用对js封装过的jquery等插件来来更加方便的进行dom操作 1.dom是什么? 对于JavaS ...

  4. js的DOM操作整理(整理)

    js的DOM操作整理(整理) 一.总结 一句话总结: dom操作有用原生js的dom操作,也可以用对js封装过的jquery等插件来更加方便的进行dom操作 1.dom是什么? 对于JavaScrip ...

  5. Javascript的DOM操作 - 你真的了解吗?

    摘要 想稍微系统的说说对于DOM的操作,把Javascript和jQuery常用操作DOM的内容归纳成思维导图方便阅读,同时加入性能上的一些问题. 前言 在前端开发的过程中,javascript极为重 ...

  6. 原生js封装dom操作库

    var utils = (function(window) { var flag = "getComputedStyle" in window; function win(attr ...

  7. 5月16日上课笔记-js中DOM操作

    一.DOM操作 DOM节点的操作 增加 删除 修改 节点的信息: nodeName 获取节点的标签名 parentNode 获取父节点 childNodes IE忽略回车换行,chrome回车换行是文 ...

  8. js函数 DOM操作

    回学校了两天请了两天假,数组和方法的内容周末一定补上! 今天介绍一下JavaScript函数 Function 一.基础内容 1.定义 函数是由事件驱动的或者当它被调用时执行的可重复使用的代码块. f ...

  9. 总结js常用的dom操作(js的dom操作API)

    转载:https://www.haorooms.com/post/js_dom_api 前言 很多同学用惯了jquery操作dom,让他们用js操作的时候,常常力不从心,本文总结了常用的js的dom操 ...

随机推荐

  1. linux 下动态链接实现原理

    符号重定位 讲动态链接之前,得先说说符号重定位. c/c++ 程序的编译是以文件为单位进行的,因此每个 c/cpp 文件也叫作一个编译单元(translation unit), 源文件先是被编译成一个 ...

  2. 笔记:BroadcastReceiver的运行过程

    广播概述 广播用来在组件之间传递消息,可以是同进程或跨进程. 广播机制是基于发布订阅的事件驱动模型,使用上比Binder通信(跨进程接口回调)更低耦合.简单. ActivityManagerServi ...

  3. python 使用多线程进行并发编程/互斥锁的使用

    import threading import time """ python的thread模块是比较底层的模块,python的threading模块是对thread做了 ...

  4. [Python列表]-索引

    Python 列表(List) 前言 序列是Python中最基本的数据结构.序列中的每个元素都分配一个数字 - 它的位置,或索引,第一个索引是0,第二个索引是1,依此类推. Python有6个序列的内 ...

  5. Spring boot 配置文件参数映射到配置类属性

    [参考文章]:SpringBoot之@EnableConfigurationProperties分析 [参考文章]:在Spring Boot中使用 @ConfigurationProperties 注 ...

  6. IDEA 图标介绍。 缓存和索引介绍、清理方法和Debug使用

    一.图标 二.缓存和索引 IntelliJ IDEA 的缓存和索引主要是用来加快文件查询,从而加快各种查找.代码提示等操作的速(上图中的图标能这样显示也是靠索引).某些特殊条件下,IntelliJ I ...

  7. DevOps - CI - 持续集成(Continuous Integration)

    初见 持续集成是什么? 持续集成基础概念介绍 持续集成服务器与工具集 了解 敏捷开发中的持续集成 使用Jenkins进行持续集成 案例 gitlab+gerrit+jenkins持续集成框架 使用Ge ...

  8. web自动化测试---测试中其他一些常用操作

    一些其他常用操作如下: 1.最大化浏览器窗口 driver.maximize_window() 2.后退 driver.back() 3.前进 driver.forward() 4.刷新操作 driv ...

  9. 【Promise】Promise实现请求超时处理(加强版)

    昨天闲来无事,于是把之前写过的promise优化了一下,代码如下: /*写文件.追加写.读文件*/ var fs = require('fs'); function wrapper(fn,contex ...

  10. salesforce零基础学习(九十)项目中的零碎知识点小总结(三)

    本次的内容其实大部分人都遇到过,也知道解决方案.但是因为没有牢记于心,导致问题再次出现还是花费了一点时间去排查了原因.在此记录下来,好记性不如烂笔头,争取下次发现类似的现象可以直接就知道原因.废话少说 ...