第三章DOM Script DOM編程 讀書筆記javascript
訪問和修改DOM元素html
瀏覽器一般要求DOM實現和JavaScript保持相互獨立。java
<!-- 例如IE中,被稱爲JScript的JavaScript實現位於庫文件jscript.dll中,而DOM實現位於另外一個庫mshtml.dll(內
部代號Trident).這種分離技術容許其餘技術和語言,
如VBScript,受益於Trident所提供的DOM功能和渲染功能。
Safari使用Webkit的WebCore處理DOM和渲染,具備一個分離的JavaScriptCore引擎。
Google Chrome也使用Webkit的WebCore庫渲染頁面,但實現了本身的JavaScript引擎V8.
在Firefox中,JavaScript實現了TraceMonkey,與其Gwcko渲染引擎相分離。-->chrome
訪問DOM元素編程
function innerHTMLLoop(){ for(var count=0; count<15000; count++){ document.getElementById("h").innerHTML+="a"; } }
每次循環單元中,都對DOM元素訪問兩次,一次次讀innerHTML屬性,一次寫。數組
使用局部變量存儲更新後的內容,在循環結束時一次性寫入:瀏覽器
function innerHTMLLoop(){ var content=" "; for(var count=0; count<15000; count++){ content+="a"; } document.getElementById("h").innerHTML+="content"; }
在全部瀏覽器中,新版本運行速度都要快得多。緩存
結論:訪問DOM越多,代碼的執行速度就越慢。
「輕輕的觸摸DOM」,儘可能保持在ECMAScript範圍內。ide
比較innerHTML和純DOM,例如createElement()函數
兩種方式建立一個1000行的表
1.構造一個HTML字符串,而後更新DOM的innerHTML屬性。
2.經過標準DOM方法document.createElement() document.createTextNode()。
innerHTML的好處在老式瀏覽器上顯而易見,新瀏覽器就不那麼明顯。
使用DOM方法反之。
若是在一個性能苛刻的操做中更新大一塊HTML頁面,innerHTML在大多數瀏覽器中執行更快。
但對於大多很多天常操做而言,其差別並不大,因此應當根據代碼可讀性,可維護性,團隊習慣,代碼風格來綜合決定採
用哪一種方法。
節點克隆
使用DOM方法更新頁面內容的另外一個途徑是克隆已有DOM元素,而不是建立新的。
即 使用element.cloneNode() (element是一個已存在的節點)代替document.createElement();
在大多數瀏覽器上,克隆節點更有效率,但提升不太多。用克隆節點的方法從新生成前面例子中的表,
單元只建立執行復制操做,這樣只是稍微快了一點。
HTML集合
是用於存放DOM節點引用的類數組對象。下列函數的返回值就是一個集合:
document.getElementByName()
document.getElementByClassName()
document.getElementByTagName()
document.images 頁面中全部的<img>元素
document.links 全部的<a>元素
document.forms 全部表單
document.forms[0].elements 頁面中的第一個表單的全部字段
這些方法和屬性返回HTMLCollection對象 ,是一種相似數組的列表。他們不是數組(由於他們沒有諸如push()和
slice()之類的方法,可是提供料一個length屬性)
HTML集合實際上查詢文檔,當你更新信息,每次都要重複執行這種查詢這種操做。例如讀取集合中元素的數目(也就是
集合的length)。這正是低效率的來源。
遍歷數組明顯快於相同大小和內容的HTML集合,能夠將集合拷貝到數組arr中。
每次迭代過程訪問集合的length屬性,致使集合器更細,在全部瀏覽器都會產生明顯的性能損失。
優化:將集合的length屬性那個緩存到一個變量中,而後循環判斷條件中使用這個變量。
對於 任何類型的DOM 訪問,若是同一個DOM屬性或方法被訪問一次以上,最好使用一個局部變量緩存此DOM成員。
當遍歷一個集合時,第一個優化是將集合引用存儲於局部變量,並在循環以外緩存length屬性,而後,若是在循環體中
屢次訪問同一個集合元素,那麼使用局部變量緩存它。
在使用DOM API時,一般要使用針對特定操做選擇最有效的API.
例如 操做周圍的元素,或者遞歸迭代全部的子節點,你能夠使用childNode集合,或者使用nextsibling得到每一個元素
的兄弟節點。
DOM屬性諸如childNode, firstChild, nextSibling不區分元素節點和其餘類型的節點,如註釋節點和文本節點,
一般只有元素節點須要被訪問,因此在循環中,彷佛應當對節點返回類型進行檢查,過濾出非元素節點,這些檢查和過
濾都是沒必要要的DOM操做。
只返回元素節點 全部類型的節點
children childNodes
childElementCount childNodes.length
firstElementChild firstChild
lastElementChild lastChild
nextElementChild nextSibling
previousElementSibling previousSibling
以上支持 FF3.5 Safari 4 chrome2 opera9.62
IE6,7,8只支持children
遍歷children比childNodes更快,集合項更少。
也能夠用CSS選擇器
var elements=document.querySelectorAll("#menu a");
返回的是NodeList 符合條件的類數組對象,不返回HTML集合
相同的方式,
var element=document.getElementById("menu").getElementsByTagName("a");
這element將是一個html集合,將它拷貝到一個數組中,若是想獲得querySelectorAll()一樣的返回值類型的話
querySelectorAll還能夠用於聯合查詢
var errs=document.querySelectorAll("div.warning,div.notice");
能夠一次性得到這兩類節點
querySelector() 返回符合查詢條件的第一個節點