摘要:,當(dāng)元素插入后仍然保留對(duì)元素的指針。能夠獲得事件處理函數(shù),而生成的新無(wú)法獲得原先設(shè)置的事件處理函數(shù)。某些情況下,更加快速。無(wú)疑,在大多數(shù)情況下,更為快速且更加易用,但是使用的時(shí)候小心上述的那個(gè)問(wèn)題就好。
WilsonLiu"s blog 首發(fā)地址
兩者生成dom的方式有什么優(yōu)劣呢?
首先讓我們看一個(gè)小問(wèn)題再引入正題~
//錯(cuò)誤的 window.onload = function(){ var el = document.createElement("div"); el.appendChild(document.createTextNode("Hi")); for (var i = 10; i > 0; --i) document.body.appendChild(el); }; //同一元素?zé)o法重復(fù)插入,
//正確的 同時(shí)注意不要設(shè)置插入多次的元素的id,否則造成錯(cuò)誤 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,是因?yàn)楫?dāng)時(shí)我的需求是克隆一個(gè)復(fù)雜的html結(jié)構(gòu),而并非生成一個(gè)簡(jiǎn)單的dom元素。
重排與重繪上述方法,雖然能夠成功生成相同的dom元素,但是性能上是存在問(wèn)題的。
每次插入dom元素到body后,dom樹(shù)會(huì)重排,之后頁(yè)面會(huì)因?yàn)樾碌膁om元素的插入而重新繪制,這兩個(gè)過(guò)程是極其耗時(shí)的。
因此,推薦使用文檔碎片document.createDocumentFragment()。
使用方法
//利用文檔碎片 提高性能 frag相當(dāng)于一個(gè)容器 frag并不會(huì)插入body而是把frag的內(nèi)部元素全部插入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先,這個(gè)過(guò)程并不會(huì)觸發(fā)重排與重繪 }; document.body.appendChild(frag); //將生成的frag插入body中,將10此重排重繪的過(guò)程壓縮為一次
接下來(lái),進(jìn)入正題的比較
innerHTML vs createElement生成Dom的兩種方式,孰優(yōu)孰劣呢?
就我們的經(jīng)驗(yàn)看來(lái),innerHTML這種采用字符串拼接生成dom的方式似乎更加方便,并且效率更高。但是那原生的createElement又有什么優(yōu)勢(shì)呢?
以下,優(yōu)勢(shì)觀點(diǎn)來(lái)自于stack overflow的言論,翻譯的也不一點(diǎn)準(zhǔn)確,歡迎探討。
createElement,當(dāng)元素插入后仍然保留對(duì)dom元素的指針。而innerHTML插入后,并沒(méi)有對(duì)dom元素的指針,你需要再通過(guò)getElementById重新選取。
createElement能夠獲得事件處理函數(shù),而innerHTML生成的新dom無(wú)法獲得原先設(shè)置的事件處理函數(shù)。
某些情況下,createElement更加快速。如果你需要反復(fù)操作字符串,在每次處理后再次插入。每次插入都將進(jìn)行解析與制作dom,在性能上會(huì)很差。
可讀性與可維護(hù)上createElement會(huì)優(yōu)秀一些
下面提供一段封裝好了的讓你方便的使用createElement的函數(shù)
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"], "."]);
你會(huì)得到這樣一個(gè)html結(jié)構(gòu)
Here is a link.
綜上,兩者各有各的好處。無(wú)疑,在大多數(shù)情況下,innerHTML更為快速且更加易用,但是使用innerHTML的時(shí)候小心上述的那個(gè)問(wèn)題就好。
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?
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/78512.html
摘要:但是如果一個(gè)值不再用到了,引用次數(shù)卻不為,垃圾回收機(jī)制卻無(wú)法釋放這塊內(nèi)存,從而導(dǎo)致內(nèi)存泄漏。內(nèi)存泄漏垃圾回收語(yǔ)言的內(nèi)存泄漏主因是不需要的引用。常見(jiàn)內(nèi)存泄漏意外的全局變量處理未定義變量的方式比較寬松未定義的變量會(huì)在全局對(duì)象創(chuàng)建一個(gè)新變量。 簡(jiǎn)答題: settimeout 與 setInterval的區(qū)別, 及對(duì)他們的內(nèi)存的分析 區(qū)別 setTimeout是在一段時(shí)間后調(diào)用指定函數(shù)(僅一...
摘要:但是如果一個(gè)值不再用到了,引用次數(shù)卻不為,垃圾回收機(jī)制卻無(wú)法釋放這塊內(nèi)存,從而導(dǎo)致內(nèi)存泄漏。內(nèi)存泄漏垃圾回收語(yǔ)言的內(nèi)存泄漏主因是不需要的引用。常見(jiàn)內(nèi)存泄漏意外的全局變量處理未定義變量的方式比較寬松未定義的變量會(huì)在全局對(duì)象創(chuàng)建一個(gè)新變量。 簡(jiǎn)答題: settimeout 與 setInterval的區(qū)別, 及對(duì)他們的內(nèi)存的分析 區(qū)別 setTimeout是在一段時(shí)間后調(diào)用指定函數(shù)(僅一...
摘要:但是如果一個(gè)值不再用到了,引用次數(shù)卻不為,垃圾回收機(jī)制卻無(wú)法釋放這塊內(nèi)存,從而導(dǎo)致內(nèi)存泄漏。內(nèi)存泄漏垃圾回收語(yǔ)言的內(nèi)存泄漏主因是不需要的引用。常見(jiàn)內(nèi)存泄漏意外的全局變量處理未定義變量的方式比較寬松未定義的變量會(huì)在全局對(duì)象創(chuàng)建一個(gè)新變量。 簡(jiǎn)答題: settimeout 與 setInterval的區(qū)別, 及對(duì)他們的內(nèi)存的分析 區(qū)別 setTimeout是在一段時(shí)間后調(diào)用指定函數(shù)(僅一...
摘要:年前就打算學(xué)習(xí)并總結(jié)一下,但是因?yàn)槟昵肮ぷ鞅容^多,所以進(jìn)展十分緩慢,現(xiàn)在終于學(xué)了一大部分,而且自己在學(xué)習(xí)開(kāi)發(fā)中也踩了不少坑也總結(jié)了不少,所以將自己踩過(guò)的坑總結(jié)一下分享出來(lái)。因?yàn)樵陧?xiàng)目中使用了,所以對(duì)于也有一個(gè)踩坑總結(jié),點(diǎn)擊鏈接。 年前就打算學(xué)習(xí)并總結(jié)一下vue2.x,但是因?yàn)槟昵肮ぷ鞅容^多,所以進(jìn)展十分緩慢,現(xiàn)在終于學(xué)了一大部分,而且自己在學(xué)習(xí)開(kāi)發(fā)中也踩了不少坑也總結(jié)了不少,所以將自己...
摘要:視覺(jué)感知測(cè)試視覺(jué)回歸測(cè)試為了解決上面提到的各種問(wèn)題,視覺(jué)感知測(cè)試孕育而生。第三種方式,無(wú)法進(jìn)行視覺(jué)感知測(cè)試結(jié)果只能進(jìn)行視覺(jué)回歸測(cè)試和上一版的繼續(xù)比較差異。 前端自動(dòng)化測(cè)試 之 視覺(jué)測(cè)試 showImg(https://segmentfault.com/img/remote/1460000014720180); 前端測(cè)試分類 showImg(https://segmentfault.co...
閱讀 2662·2021-11-18 10:02
閱讀 2198·2021-10-13 09:40
閱讀 3111·2021-09-07 10:07
閱讀 2226·2021-09-04 16:48
閱讀 1101·2019-08-30 13:18
閱讀 2539·2019-08-29 14:03
閱讀 3018·2019-08-29 12:54
閱讀 3239·2019-08-26 11:41