摘要:,当元素插入后仍然保留对元素的指针。能够获得事件处理函数,而生成的新无法获得原先设置的事件处理函数。某些情况下,更加快速。无疑,在大多数情况下,更为快速且更加易用,但是使用的时候小心上述的那个问题就好。
WilsonLiu"s blog 首发地址
两者生成dom的方式有什么优劣呢?
首先让我们看一个小问题再引入正题~
//错误的 window.onload = function(){ var el = document.createElement("div"); el.appendChild(document.createTextNode("Hi")); for (var i = 10; i > 0; --i) document.body.appendChild(el); }; //同一元素无法重复插入,
//正确的 同时注意不要设置插入多次的元素的id,否则造成错误 window.onload = function(){ var el = document.createElement("div"); el.appendChild(document.createTextNode("Hi")); for (var i = 10; i > 0; --i) document.body.appendChild(el.cloneNode(true)); };
上述之所以要用clone,是因为当时我的需求是克隆一个复杂的html结构,而并非生成一个简单的dom元素。
重排与重绘上述方法,虽然能够成功生成相同的dom元素,但是性能上是存在问题的。
每次插入dom元素到body后,dom树会重排,之后页面会因为新的dom元素的插入而重新绘制,这两个过程是极其耗时的。
因此,推荐使用文档碎片document.createDocumentFragment()。
使用方法
//利用文档碎片 提高性能 frag相当于一个容器 frag并不会插入body而是把frag的内部元素全部插入body window.onload = function(){ var frag = document.createDocumentFragment(); var el = document.createElement("div"); el.appendChild(document.createTextNode("Hi")); for (var i = 10; i > 0; --i) frag.appendChild(el.cloneNode(true)); //先将生成的dom全部插入frag先,这个过程并不会触发重排与重绘 }; document.body.appendChild(frag); //将生成的frag插入body中,将10此重排重绘的过程压缩为一次
接下来,进入正题的比较
innerHTML vs createElement生成Dom的两种方式,孰优孰劣呢?
就我们的经验看来,innerHTML这种采用字符串拼接生成dom的方式似乎更加方便,并且效率更高。但是那原生的createElement又有什么优势呢?
以下,优势观点来自于stack overflow的言论,翻译的也不一点准确,欢迎探讨。
createElement,当元素插入后仍然保留对dom元素的指针。而innerHTML插入后,并没有对dom元素的指针,你需要再通过getElementById重新选取。
createElement能够获得事件处理函数,而innerHTML生成的新dom无法获得原先设置的事件处理函数。
某些情况下,createElement更加快速。如果你需要反复操作字符串,在每次处理后再次插入。每次插入都将进行解析与制作dom,在性能上会很差。
可读性与可维护上createElement会优秀一些
下面提供一段封装好了的让你方便的使用createElement的函数
function isArray(a) { return Object.prototype.toString.call(a) === "[object Array]"; } function make(desc) { if (!isArray(desc)) { return make.call(this, Array.prototype.slice.call(arguments)); } var name = desc[0]; var attributes = desc[1]; var el = document.createElement(name); var start = 1; if (typeof attributes === "object" && attributes !== null && !isArray(attributes)) { for (var attr in attributes) { el[attr] = attributes[attr]; } start = 2; } for (var i = start; i < desc.length; i++) { if (isArray(desc[i])) { el.appendChild(make(desc[i])); } else { el.appendChild(document.createTextNode(desc[i])); } } return el; }
使用方式
make(["p", "Here is a ", ["a", { href:"http://www.google.com/" }, "link"], "."]);
你会得到这样一个html结构
Here is a link.
综上,两者各有各的好处。无疑,在大多数情况下,innerHTML更为快速且更加易用,但是使用innerHTML的时候小心上述的那个问题就好。
Advantages of createElement over innerHTML?
Advantages of createElement over innerHTML?
JavaScript: Is it better to use innerHTML or (lots of) createElement calls to add a complex div structure?
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/78512.html
摘要:但是如果一个值不再用到了,引用次数却不为,垃圾回收机制却无法释放这块内存,从而导致内存泄漏。内存泄漏垃圾回收语言的内存泄漏主因是不需要的引用。常见内存泄漏意外的全局变量处理未定义变量的方式比较宽松未定义的变量会在全局对象创建一个新变量。 简答题: settimeout 与 setInterval的区别, 及对他们的内存的分析 区别 setTimeout是在一段时间后调用指定函数(仅一...
摘要:但是如果一个值不再用到了,引用次数却不为,垃圾回收机制却无法释放这块内存,从而导致内存泄漏。内存泄漏垃圾回收语言的内存泄漏主因是不需要的引用。常见内存泄漏意外的全局变量处理未定义变量的方式比较宽松未定义的变量会在全局对象创建一个新变量。 简答题: settimeout 与 setInterval的区别, 及对他们的内存的分析 区别 setTimeout是在一段时间后调用指定函数(仅一...
摘要:但是如果一个值不再用到了,引用次数却不为,垃圾回收机制却无法释放这块内存,从而导致内存泄漏。内存泄漏垃圾回收语言的内存泄漏主因是不需要的引用。常见内存泄漏意外的全局变量处理未定义变量的方式比较宽松未定义的变量会在全局对象创建一个新变量。 简答题: settimeout 与 setInterval的区别, 及对他们的内存的分析 区别 setTimeout是在一段时间后调用指定函数(仅一...
摘要:年前就打算学习并总结一下,但是因为年前工作比较多,所以进展十分缓慢,现在终于学了一大部分,而且自己在学习开发中也踩了不少坑也总结了不少,所以将自己踩过的坑总结一下分享出来。因为在项目中使用了,所以对于也有一个踩坑总结,点击链接。 年前就打算学习并总结一下vue2.x,但是因为年前工作比较多,所以进展十分缓慢,现在终于学了一大部分,而且自己在学习开发中也踩了不少坑也总结了不少,所以将自己...
摘要:视觉感知测试视觉回归测试为了解决上面提到的各种问题,视觉感知测试孕育而生。第三种方式,无法进行视觉感知测试结果只能进行视觉回归测试和上一版的继续比较差异。 前端自动化测试 之 视觉测试 showImg(https://segmentfault.com/img/remote/1460000014720180); 前端测试分类 showImg(https://segmentfault.co...
阅读 2409·2021-11-18 10:02
阅读 1924·2021-10-13 09:40
阅读 3001·2021-09-07 10:07
阅读 2109·2021-09-04 16:48
阅读 1006·2019-08-30 13:18
阅读 2455·2019-08-29 14:03
阅读 2924·2019-08-29 12:54
阅读 3157·2019-08-26 11:41