使用DocumentFragment优化DOM操作
DocumentFragment 是什么 ?
DocumentFragment,文档片段接口,一个没有父对象的最小文档对象。它被作为一个轻量版的 Document 使用,就像标准的 document 一样,存储由节点(nodes)组成的文档结构。与 document 相比,最大的区别是 DocumentFragment 不是真实 DOM 树的一部分,它的变化不会触发 DOM 树的重新渲染,且不会导致性能等问题。 ———— MDN
#使用场景
如果要在一个
ul
节点中一次性插入 10000 个li
元素怎么办?
<ul id="parent">
...
</ul>
#方法一
你可能第一个想到的方法,也是最简单的方式:
var parent = document.getElementById("parent");
for (var i = 0; i < 10000; i++) {
var child = document.createElement("li");
var text = document.createTextNode("" + i);
child.appendChild(text);
parent.appendChild(child);
}
不过众所周知的原因,对 DOM
反复操作会导致页面重绘、回流,效率非常低,而且页面可能会被卡死。
#方法二
当然,更多能想到的方式应该是,先创造一个 div
节点,在内存中直接操作节点,然后把所有节点都凑在一起之后再跟 DOM
树进行交互,把所有节点都串在一个 div
上,然后再把 div
挂到 DOM
树上:
var parent = document.getElementById("parent");
var div = document.createElement("div");
for (var i = 0; i < 10000; i++) {
var child = document.createElement("li");
var text = document.createTextNode("" + i);
child.appendChild(text);
div.appendChild(child);
}
parent.appendChild(div);
只跟 DOM
树交互一次,性能方面肯定是大有改善的,不过额外插入了一个 div
,如果说不是跟 div
之类的节点进行交互呢,比如在 table
中插入 th
、td
?
#方法三
这个时候,就到了 DocumentFragment
上场了,翻译过来就是文档片段的意思。
简单来说就是在内存中提供了一个 DOM
对象,当我们需要频繁操作 DOM
的时候,可以在内存先中创建一个 DocumentFragment
文档片段,然后对这个文档片段中进行一系列频繁的 DOM
操作,当操作结束后直接插入真实的 DOM
节点中,这样所有的节点会被一次插入到真实的文档中,而这个操作仅发生一个重绘的操作。
可以当做是上面一个例子的不需要 div
中转版本,插入的时候,直接用其子元素替换其本身,非常完美。
var parent = document.getElementById("parent");
var frag = document.createDocumentFragment();
for (var i = 0; i < 10000; i++) {
var child = document.createElement("li");
var text = document.createTextNode("" + i);
child.appendChild(text);
frag.appendChild(child);
}
parent.appendChild(frag);
#总结
当应对于频繁的DOM
操作的场景,可以使用DocumentFragment
。
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- laravel dingo API返回自定义错误信息的实例
- Linux基于php-fpm模式的lamp搭建phpmyadmin的办法
- 基于laravel Request的所有方法详解
- 浅谈thinkphp的nginx配置,以及重写隐藏index.php入口文件方法
- php图片裁剪函数
- Laravel自定义 封装便捷返回Json数据格式的引用方法
- Laravel模糊查询区分大小写的实例
- laravel实现一个上传图片的接口,并建立软链接,访问图片的方法
- Laravel中validation验证 返回中文提示 全局设置的方法
- laravel5表单唯一验证的实例代码
- 实现laravel 插入操作日志到数据库的方法
- laravel validate 设置为中文的例子(验证提示为中文)
- Laravel 使用查询构造器配合原生sql语句查询的例子
- php面试实现反射注入的详细方法
- laravel框架 api自定义全局异常处理方法