createElement与createDocumentFragment的点点区别小结


Posted in Javascript onDecember 19, 2011

网上可以搜到的大部分都是说使用createDocumentFragment主要是因为避免因createElement多次添加到document.body引起的效率问题,比如:

var arrText=["1","2","3","4","5","6","7","8","9","10"]; 
for(var i=0;i<arrText.length;i++){ 
var op=document.createElement("P"); 
var oText=document.createTextNode(arrText[i]); 
op.appendChild(oText); 
document.body.appendChild(op); 
} 
var arrText=["1","2","3","4","5","6","7","8","9","10"]; 
var oFrag=document.createDocumentFragment(); 
for(var i=0;i<arrText.length;i++){ 
var op=document.createElement("P"); 
var oText=document.createTextNode(arrText[i]); 
op.appendChild(oText); 
oFrag.appendChild(op); 
} 
document.body.appendChild(oFrag);

(声明:这是我google的第一个例子,并不代表对原作者有任何意见,原文地址http://www.cnitblog.com/asfman/articles/32614.html)
这个说法并没有错,但是并不严谨,因为像这种用法,主要还是用在目标节点是已存在并且有一部分内容的情况下,比如上面例子中的body元素,如果目标节点并不存在或者为空,完全可以用createElement创建一个相同的元素,操作之后再使用一次appendChild或者replaceChild来达到相同的目的,这样也不存在重复刷新的问题。
虽说我平时都是把两者混着用,但是还是得明白两者之间的一点区别:
第一:
createElement创建的元素可以使用innerHTML,createDocumentFragment创建的元素使用innerHTML并不能达到预期修改文档内容的效果,只是作为一个属性而已。两者的节点类型完全不同,并且createDocumentFragment创建的元素在文档中没有对应的标记,因此在页面上只能用js中访问到。
demo:
<!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>

第二:另一个最主要的区别就是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>
Javascript 相关文章推荐
js jquery数组介绍
Jul 15 Javascript
js创建一个input数组并绑定click事件的方法
Jun 12 Javascript
使用AngularJS制作一个简单的RSS阅读器的教程
Jun 18 Javascript
理解javascript正则表达式
Mar 08 Javascript
JavaScript地理位置信息API
Jun 11 Javascript
一篇文章搞定JavaScript类型转换(面试常见)
Jan 21 Javascript
使用Vue完成一个简单的todolist的方法
Dec 01 Javascript
JavaScript实现AOP详解(面向切面编程,装饰者模式)
Dec 19 Javascript
小程序表单认证布局及验证详解
Jun 19 Javascript
Vue 实现创建全局组件,并且使用Vue.use() 载入方式
Aug 11 Javascript
Vue3.0的优化总结
Oct 16 Javascript
Vue 打包的静态文件不能直接运行的原因及解决办法
Nov 19 Vue.js
javascript面向对象编程代码
Dec 19 #Javascript
用jQuery模拟页面加载进度条的实现代码
Dec 19 #Javascript
javascript管中窥豹 形参与实参浅析
Dec 17 #Javascript
jquery focus(fn),blur(fn)方法实例代码
Dec 16 #Javascript
JS获取整个页面文档的实现代码
Dec 15 #Javascript
jQuery版仿Path菜单效果
Dec 15 #Javascript
cnblogs 代码高亮显示后的代码复制问题解决实现代码
Dec 14 #Javascript
You might like
PHP详细彻底学习Smarty
2008/03/27 PHP
简单的php中文转拼音的实现代码
2014/02/11 PHP
编译PHP报错configure error Cannot find libmysqlclient under usr的解决方法
2014/06/27 PHP
ThinkPHP5实现作业管理系统中处理学生未交作业与已交作业信息的方法
2016/11/12 PHP
Laravel如何实现自动加载类
2019/10/14 PHP
asp批量修改记录的代码
2008/06/25 Javascript
JSQL 批量图片切换的实现代码
2010/05/05 Javascript
基于jQuery的图片大小自动适应实现代码
2010/11/17 Javascript
基于MVC5和Bootstrap的jQuery TreeView树形控件(一)之数据支持json字符串、list集合
2016/08/11 Javascript
详解Vue学习笔记入门篇之组件的内容分发(slot)
2017/07/17 Javascript
js Date()日期函数浏览器兼容问题解决方法
2017/09/12 Javascript
详解vuex结合localstorage动态监听storage的变化
2018/05/03 Javascript
微信小程序chooseImage的用法(从本地相册选择图片或使用相机拍照)
2018/08/22 Javascript
ES6 如何改变JS内置行为的代理与反射
2019/02/11 Javascript
JS合并两个数组的3种方法详解
2019/10/24 Javascript
微信小程序实现单个卡片左滑显示按钮并防止上下滑动干扰功能
2019/12/06 Javascript
[34:44]Liquid vs TNC Supermajor 胜者组 BO3 第二场 6.4
2018/06/05 DOTA
python 正则表达式 概述及常用字符
2009/05/04 Python
python网页请求urllib2模块简单封装代码
2014/02/07 Python
Python中统计函数运行耗时的方法
2015/05/05 Python
Python提取网页中超链接的方法
2016/09/18 Python
Python简单遍历字典及删除元素的方法
2016/09/18 Python
Python3正则匹配re.split,re.finditer及re.findall函数用法详解
2018/06/11 Python
python3通过qq邮箱发送邮件以及附件
2020/05/20 Python
Django静态文件加载失败解决方案
2020/08/26 Python
手机配件第一品牌:ZAGG
2017/05/28 全球购物
IRO美国官网:法国服装品牌
2018/03/06 全球购物
电大学习个人自我评价范文
2013/10/04 职场文书
工业自动化专业毕业生推荐信
2013/11/18 职场文书
行政前台岗位职责
2013/12/04 职场文书
会计专业的自荐信
2013/12/12 职场文书
学雷锋演讲稿
2014/03/04 职场文书
OpenCV-Python实现油画效果的实例
2021/06/08 Python
Win11任务栏太宽了怎么办?一招解决Win11任务栏太宽问题
2021/11/21 数码科技
小程序实现侧滑删除功能
2022/06/25 Javascript
spring boot实现文件上传
2022/08/14 Java/Android