1.createDocumentFragment()方法,是用来创建一个虚拟的节点对象,或者说,是用来创建文档碎片节点。它可以包含各种类型的节点,在创建之初是空的。

2.DocumentFragment节点不属于文档树,继承的parentNode属性总是null。它有一个很实用的特点,当请求把一个DocumentFragment节点插入文档树时,插入的不是DocumentFragment自身,而是它的所有子孙节点,即插入的是括号里的节点。这个特性使得DocumentFragment成了占位符,暂时存放那些一次插入文档的节点。它还有利于实现文档的剪切、复制和粘贴操作。

另外,当需要添加多个dom元素时,如果先将这些元素添加到DocumentFragment中,再统一将DocumentFragment添加到页面,会减少页面渲染dom的次数,效率会明显提升。

3.如果使用appendChid方法将原dom树中的节点添加到DocumentFragment中时,会删除原来的节点。

4.createDocumentFragment()方法和createElement()方法的区别:

(1)需要很多的插入操作和改动,继续使用类似于下面的代码则会很有问题

var ul = document.getElementById("ul");
for (var i = 0; i < 20; i++) {
var li = document.createElement("li");
li.innerHTML = "index: " + i;
ul.appendChild(li);

由于每一次对文档的插入都会引起重新渲染(计算元素的尺寸,显示背景,内容等),所以进行多次插入操作使得浏览器发生了很多次渲染,效率是比较低的。这是我们提倡通过减少页面的渲染来提高DOM操作的效率的原因。一个优化的方法是将要创建的元素写到一个字符串上,然后一次性写到innerHTML上,这种利用浏览器对innerHTML的解析确实是相比上面的多次插入快了很多。但是构造字符串灵活性上面比较差,很难符合创建各种各样的DOM元素的需求。利用DocumentFragment,可以弥补这两个方法的不足。

因为文档片段存在于内存中,并不在DOM中,所以将子元素插入到文档片段中时不会引起页面回流(对元素位置和几何上的计算),因此使用DocumentFragment可以起到性能优化的作用。例如上面的代码就可以改成下面的片段

var ul = document.getElementById("ul");
var fragment = document.createDocumentFragment();
for (var i = 0; i < 20; i++) {
var li = document.createElement("li");
li.innerHTML = "index: " + i;
fragment.appendChild(li);
}
ul.appendChild(fragment);

(2)createElement创建的元素可以使用innerHTML,createDocumentFragment创建的元素使用innerHTML并不能达到预期修改文档内容的效果,只是作为一个属性而已。两者的节点类型完全不同,createElement创建的是元素节点,节点类型为1,createDocumentFragment创建的是文档碎片,节点类型是11。并且createDocumentFragment创建的元素在文档中没有对应的标记,因此在页面上只能用js中访问到。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title></title>
<style type="text/css">
#outer{ height: 200px; border: 1px solid #006400;}
</style>
</head>
<body>
<div id="outer">
</div>
<input type="button" value="createElement" id="btn_1"/><input type="button" value="createDocumentFragment" id="btn_2"/>
<script type="text/javascript">
var fragment_1 = document.createDocumentFragment();
fragment_1.innerHTML = '<p>我是一个粉刷匠</p>';
document.body.appendChild(fragment_1);
var fragment_2 = document.createElement('p');
fragment_2.innerHTML = '粉刷本领强';
document.body.appendChild(fragment_2);
</script>
</body>
</html>

(3)createElement创建的元素可以重复操作,添加之后就算从文档里面移除依旧归文档所有,可以继续操作,但是createDocumentFragment创建的元素是一次性的,添加之后再就不能操作了(说明:这里的添加并不是添加了新创建的片段,因为上面说过,新创建的片段在文档内是没有对应的标签的,这里添加的是片段的所有子节点)。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title></title>
<style type="text/css">
#outer{ height: 200px; border: 1px solid #006400;}
</style>
</head>
<body>
<div id="outer">
</div>
<input type="button" value="createElement" id="btn_1"/><input type="button" value="createDocumentFragment" id="btn_2"/>
<script type="text/javascript">
function $(id){
return document.getElementById(id);
}
var outer = $('outer');
var inner = $('inner');
$('btn_1').onclick = function(){
var div = document.createElement('div');
div.innerHTML = '<p>测试createElement</p>';
document.body.appendChild(div);
setTimeout(function(){
outer.appendChild(div);
setTimeout(function(){
outer.removeChild(div);
},1000)
},1000)
}
$('btn_2').onclick = function(){
var p = document.createElement('p');
p.innerHTML = '测试DocumentFragment';
var fragment = document.createDocumentFragment();
fragment.appendChild(p);
fragment.innerHTML = '<p>测试DocumentFragment</p>';
fragment.innerHTML = '<span>测试DocumentFragment</span>';
document.body.appendChild(fragment);
setTimeout(function(){
outer.appendChild(fragment);//报错,因为此时文档内部已经能够不存在fragment了
setTimeout(function(){
outer.removeChild(fragment);
},1000)
},1000)
}
</script>
</body>
</html>

(4)通过createElement新建元素必须指定元素tagName,因为其可用innerHTML添加子元素。通过createDocumentFragment则不必。

(5)通过createElement创建的元素插入文档后,还可以取到创建时的返回值,即上面例子中createElement还是创建的那个div元素,而createDocumentFragment创建的元素插入到文档后,就不能访问创建时的返回值了,相当于把自己创建的文档片段直接挪到文档中了。

5.createDocumentFragment()方法和createElement()方法的共同点:

(1)添加子元素后返回值都是新添加的子元素,因此,可通过下面的方法利用innerHTML为createDocumentFragment添加子元素:

var fragment = document.createDocumentFragment();
var ret = fragment.appendChild(document.createElement('div'));
ret.innerHTML = 'by innerHTML ';
test1.appendChild(fragment);

(2)都可以通过appendChild添加子元素,且子元素必须是node类型,不能为文本。

(3)若添加的子元素是文档中存在的元素,则通过appendChild在为其添加子元素时,会从文档中删除之前存在的元素。

6.DocumentFragment是没有父节点的最小的文档对象,用于存储HTML和XML片段。DocumentFragment对象继承Node,所以它有Node的所有属性方法,完全可以操作Node(NodeList)那样操作DocumentFragment。此外W3C对DocumentFragment也定义了一些另外的属性和方法,但是由于多数浏览器都没有实现,从兼容性上来说不推荐使用这些属性。具体有哪些属性方法可以参考MDN说明。

创建DocumentFragment的方法有两种,document.createDocumentFragment()和new Fragment()。对于document.createDocumentFragment(),所有浏览器都支持(包括IE6),而构造函数方法就不是所有浏览器都有效了(IE没有实现该方法)。所以从兼容性上来说推荐使用document.createDocumentFragment()。
---------------------
原文:https://blog.csdn.net/qiao13633426513/article/details/80243058

createDocumentFragment()用法总结的更多相关文章

  1. 虚拟节点操作——DocumentFragment

    文章中转站: DocumentFragment对象 createDocumentFragment()用法总结 深入理解DOM节点类型第四篇——文档片段节点DocumentFragment

  2. js 在光标位置插入内容

    原文:https://blog.csdn.net/smartsmile2012/article/details/53642082 createDocumentFragment()用法: https:/ ...

  3. document.createDocumentFragment()的用法

    createDocumentFragment有什么作用呢? 调用多次document.body.append(),每次都要刷新页面一次.效率也就大打折扣了,而使用document_createDocu ...

  4. createElement与createDocumentFragment的点点区别

    在DOM操作里,createElement是创建一个新的节点,createDocumentFragment是创建一个文档片段. 网上可以搜到的大部分都是说使用createDocumentFragmen ...

  5. js学习日记 (1)createDocumentFragment() ES6 => 箭头

    只能说是会用和记载,深入理解还需时间. 有关性能优化: 使用createdocumentfragment()方法可以创建某个具有节点该有的所有属性的节点. 使用情况:  提取文档中的某个小部分,修改文 ...

  6. createElement与createDocumentFragment的一些小区别

    在DOM操作里,createElement是创建一个新的节点,createDocumentFragment是创建一个文档片段. 网上可以搜到的大部分都是说使用createDocumentFragmen ...

  7. mui初级入门教程(三)— html5+ XMLHttpRequest 与mui ajax用法详解

    文章来源:小青年原创发布时间:2016-05-29关键词:mui,html5+,XMLHttpRequest,ajax,懒加载转载需标注本文原始地址: http://zhaomenghuan.gith ...

  8. DocumentFragment的相关用法

    额,今天看了vue1.0关于模板渲染的知识,认识了DocumentFragment这个东西,它相当于一个节点容器,我们对他使用appendChild时,只有它的子节点会被插入进去,它本身不会插入进去, ...

  9. EditText 基本用法

    title: EditText 基本用法 tags: EditText,编辑框,输入框 --- EditText介绍: EditText 在开发中也是经常用到的控件,也是一个比较必要的组件,可以说它是 ...

随机推荐

  1. aws小结

    IAM:亚马逊访问权限控制(AWS Identity and Access Management ) https://www.cnblogs.com/andy9468/p/10635019.html ...

  2. react native获取屏幕的宽度和高度

    var Dimensions = require('Dimensions'); var {width,height} = Dimensions.get("window");//第一 ...

  3. 20180328 Redis和MSMQ

    以前接触的页面记录多为session或者传递的方式短暂记忆.今天接触了一个Redis作为缓存的想法,在之前我也是用过Redis ,但是只是作为异步任务系统记录是否执行成功使用,目前看来用Redis也可 ...

  4. poi api工具

    ------------官网api地址 http://poi.apache.org/apidocs/index.html ------------官方下载地址 http://poi.apache.or ...

  5. 小程序 login

    app.json : 配置文件 => 文件路径 pages .配置窗口 window.底部导航 tabBar .请求超时时间 networkTimeout app.js : 请求路口文件 wx. ...

  6. 循环匹配出图片地址(即src属性)

    <script type="text/javascript"> //思路分两步:作者(yanue). //1,匹配出图片img标签(即匹配出所有图片),过滤其他不需要的 ...

  7. syslog-ng内容讲解

    一.基础syslog-ng作为syslog的替代工具,可以完全替代syslog的服务,并且通过定义规则,实现更好的过滤功能.系统自带版本: 引用 # rpm -qa|grep syslog-ngsys ...

  8. 【LeetCode每天一题】Find First and Last Position of Element in Sorted Array(找到排序数组中指定元素的开始和结束下标)

    Given an array of integers nums sorted in ascending order, find the starting and ending position of ...

  9. MySql语句常用命令整理---单表查询

    初始化t_employee表 创建t_employee表 -- DROP TABLE IF EXISTS test; CREATE TABLE t_employee ( _id INTEGER PRI ...

  10. SQL简单操作

    删除表数据,保留表结构: delete from employee 将删除所有的记录 delete from employee where lastname = 'May' 这条语句是从emplyee ...