這裡是修真院前端小課堂,每篇分享文從 【背景介紹】【知識剖析】【常見問題】【解決方案】【編碼實戰】【擴展思考】【更多討論】【參考文獻】 八個方面深度解析前端知識/技能,本篇分享的是: 【常見的DOM操作有哪些】 1.背景介紹 什麼是DOM?簡單地說,DOM是一套對文檔的內容進行抽象和概念化的方法 在 ...
這裡是修真院前端小課堂,每篇分享文從
【背景介紹】【知識剖析】【常見問題】【解決方案】【編碼實戰】【擴展思考】【更多討論】【參考文獻】
八個方面深度解析前端知識/技能,本篇分享的是:
【常見的DOM操作有哪些】
1.背景介紹
什麼是DOM?簡單地說,DOM是一套對文檔的內容進行抽象和概念化的方法
在現實世界里,人們對所謂的'世界對象模型'都不會陌生,例如,當用'汽車'、'房子'和'樹'等名詞來稱呼日常生活環境里的事物時,我們都可以百分百的肯定對方知道我們說的是什麼,這是因為人們在對這些名詞所代表的的東西有著相同的認知。於是,當對別人說"汽車停在車庫裡"時,可以斷定他們不會理解為"小鳥關在壁櫥里"
我們的"世界對象模型"不進可以用來描述客觀存在的事物,還可以同來描述抽象概念。例如,假設有個人想我問路,而我給出的答案是"左邊第三棟房子",這個答案有沒有意義取決於那個人能夠理解"左邊"和"第三"的含義。如果他不會數數或者分不清左右,則不管他是否理解這幾個概念,我的回答對他都不會有任何的幫助。在現實世界中,正是因為大家對抽象的"世界對象模型"有著基本的共識,人們才能用非常簡單的話來表達出複雜的含義並得到對方的理解。
而DOM的定義則是由W3C所制定的標準,定義為"一個與系統平臺和編程語言無關的介面,程式和腳本可以通過這個介面動態地訪問和修改文檔的內容`、結構和樣式。"
2.知識剖析
2.1. 節點是什麼
節點這個詞是一個網路用語,代表了網路中的一個連接點。一個網路就是由一些節點構成的集合。
在現實世界中,一切事物都由原子構成。原子就是現實世界的節點。但是原子同樣還可以進一步分解為更細小的亞原子微粒。這些亞原子微粒同樣也是節點。
DOM也是同樣的情況。文檔是由節點構成的集合,只不過此時的節點是文檔樹上的樹枝和樹葉而已。
在DOM中有許多不同類型的節點。就像原子包含著亞原子微粒那樣,也有很多類型的DOM節點包含著其他類型的節點。接下來我們先看看其中的三種:元素節點、文本節點和屬性節點。
2.2. 元素節點
在DOM中的原子就是元素節點。
像是我們現在所看到的這個網頁,我們在編寫時,會用到諸如<body>、<head>、<p>這些元素。如果把Web上的文檔比作一座大廈,那麼元素就是建造這座大廈的磚塊,這些元素在在文檔中的佈局形成了文檔的結構。元素可以包含其他的元素,在我們所看到的頁面頁中,內容都被包含在在一個<section>元素的內部。而唯一沒有被包含在其他元素中的唯一元素是'<html>',他和我們的節點樹的根元素,其他的所有元素都被包含在'<html>'中。
網頁的部分節點樹
2.3. 文本節點
元素節點只是節點類型的一種。如果一份文檔完全有一些空白元素構成,他將有一個結構,但這份文檔本身將不會包含什麼內容。
在我們的ppt首頁中,'<p>'元素包含著文本,'分享人:劉洪利'。他就是一個文本節點。在html文檔里,文本節點總是被包含在元素節點的內部。
2.4. 屬性節點
屬性節點用來對元素做出更具體的描述。例如,幾乎所有的元素都有一個title屬性,而我們可以利用這個屬性對包含在元素里的東西做出準確的描述:'<p title="a gentle reminder">這是一個帶有溫馨提示的p標簽</p>'
在DOM中,title="a gentle reminder"是一個屬性節點。因為屬性總是被放在起始標簽里,所以屬性節點總是被包含在元素節點中。並非所有的標簽都包含著屬性,但是所有的屬性都被元素包含。
元素的構成
2.5. 常見的DOM操作
獲取DOM
通過使用 getElementById() 方法匹配元素的id屬性來訪問元素節點,對元素節點進行操作
通過使用 getElementsByTagName() 方法匹配元素的tagName來訪問元素節點,對元素節點進行操作
通過使用 getElementsByClassName() 方法匹配元素的className來訪問元素節點,對元素節點進行操作
值得註意的是, getElementsByTagName() 和 getElementsByClassName() 這兩種方法因為其訪問的是節點中的可能為複數的屬性,所以得到的會是一個以數組的形式來體現出來的元素節點集合,我們可以通過列印獲取到的DOM節點來判斷類型
DOM事件
onclick事件---當用戶點擊時執行
onload事件---當用戶進入時執行
onunload事件---用用戶離開時執行
onmouseover事件---當用戶滑鼠指針移入時執行
onmouseout事件---當用戶滑鼠指針移出時執行
onmousedown事件---當用戶滑鼠摁下時執行
onmouseup事件---當用戶滑鼠鬆開時執行
3. 常見問題
如何通過class和tag調用元素?如何對其設置屬性?
4.解決方案
在一個頁面中常常有多個class相同的元素,也有多個標簽相同的元素,在調用時方法如下
5. 擴展思考
onblur事件---當對象失去焦點時發生
onchange事件---當對象域的值被改變時發生
button 事件---屬性可返回一個整數,指示當事件被觸發時哪個滑鼠按鍵被點擊。
更多的事件就不一一的描述了,有興趣的同學可以去看下這個
6. 參考文獻
書籍:《JavaScript DOM編程藝術》
網址:w3school
7.更多討論
Q:dom操作是非同步的嗎
A:dom的操作其實是同步的,但是渲染是非同步的。因為JavaScript引擎線程跟GUI渲染線程是互斥的,即我執行的時候,你就靠邊站,我執行完你才能執行。具體的可以看下這篇文章https://segmentfault.com/a/1190000005803237----《關於修改DOM是非同步還是同步的問題》
Q:除了getElementsByClassName()、getElementsByTagName()、getElementById()還有什麼可以獲取dom節點的方法
A:
1.通過節點屬性得到元素
1)node屬性:來獲取節點的名稱、類型、值。
js代碼:
window.onload=function(){ 子節點
var pox = document.getElementById('pox');
alert(pox.childNodes.length) //子節點數量
alert(pox.childNodes[0].nodeValue); // 第一個子節點的內容
alert(pox.firstChild.nodeValue); // 第一個子節點的內容
alert(pox.lastChild.nodeValue); // 最後一個節點的內容
};
註意:node只能獲取當前節點的東西,在上面的js代碼中node本身把節點指針放在元素上,所以本身沒有value值,
2.層次節點屬性:層級節點可以分為父子節點和兄弟節點,通過當前節點可以獲取其他層次的節點。
2.1)子節點childNodes、第一個位元組點firstChilds、最後一個子節點lastChilds。
js代碼:
window.onload=function(){ 子節點
var pox = document.getElementById('pox');
alert(pox.childNodes.length) //子節點數量
alert(pox.childNodes[0].nodeValue); // 第一個子節點的內容
alert(pox.firstChild.nodeValue); // 第一個子節點的內容
alert(pox.lastChild.nodeValue); // 最後一個節點的內容
};
2.2)父節點parentChild、兄弟節點previousSibing,nextSibing。
js代碼:
window.onload=function(){ 父節點,上下節點
var pox = document.getElementById('pox');
alert(pox.parentNode); //pox節點的父節點body節點
alert(pox.firstChild.nextSibling); //pox節點的子節點中第一個節點的下一個節點
alert(pox.lastChild.previousSibling); //pox節點的子節點中最後一個節點的上一個節點
alert(pox.lastChild.previousSibling.nodeName)
};
本回答摘自-----------《獲取元素節點(DOM基礎 )》http://blog.csdn.net/u010928364/article/details/43935875
Q:dom操作的最佳實踐應該是什麼樣的
A:
1. 平穩退化:正確的使用JavaScript腳本,讓訪問者在他們瀏覽器不支持JavaScript的情況下仍能順利的瀏覽你的網站,即是有些功能無法使用,但最基本的操作仍能順利完成。
2. 分離JavaScript:將HTML內部DOM事件分離到外部來,保證HTML的純凈,同時可以在外部js文件通過獲取DOM節點來給這個節點添加事件的形式來運行外部JavaScript文件。
3. 向後相容:因為不同瀏覽器對JavaScript的支持程度也不一致,絕大多數的瀏覽器都可以或多或少的支持JavaScript,,但比較古老的瀏覽器卻很有可能無法理解DOM提供的方法和腳本。因此,我們通過以下幾點來確保那些古老的瀏覽器不會因為腳本代碼而出問題。
3.1. 對象檢測:檢測瀏覽器對JavaScript的支持程度。我們可以通過將某種方法打包在一個if語句中,然後根據這條語句的條件表達式的求值結果為true(這個方法存在)還是false(這個方法不存在)來決定應該採取怎麼樣的行動。
例如,如果有一個使用了getElementById()方法的函數麽就可以在調用getElementById()方法之前先檢查用戶所用的瀏覽器是否支持這個方法。在使用對象檢查時,一定要刪除方法名後面的圓括弧,如果不刪掉,測試的將是方法的結果,無論方法是否存在
代碼:
if( ! document.getElementById ) return false;
4. 性能考慮: 為保證應用流暢的運行,在為文檔編寫和應用腳本時,需要註意一些問題。
4.1. 儘量少訪問DOM和儘量減少標記
訪問DOM的方式對腳本性能會產生很大的影響。例如當我們需要訪問html頁面中所有的div元素來找到我們想要的那個節點,我們不知道會有多少div元素來面對著我們,所以瀏覽器會去搜索整個DOM樹,從中查找可能匹配的元素。
另一個是儘量減少文檔中的標記數量。過多不必要的元素只會增加DOM樹的規模,進而增加遍歷DOM樹以查找特定元素的時間。
4.2. 合併和放置腳本
我們通過合併外部JavaScript文件來減少載入頁面時發送的請求數量。減少請求數量通常都是在性能優化時優先考慮的。
4.3. 壓縮腳本
通過將腳本文件中不必要耳朵位元組,如空格和註釋統統刪除,從而達到“壓縮文件”的目的。
“我們相信人人都可以成為一個工程師,現在開始,找個師兄,帶你入門,學習的路上不再迷茫。
這裡是技能樹.IT修真院:http://www.jnshu.com,初學者轉行到互聯網行業的聚集地。"
歡迎加IT交流群565734203與大家一起討論交流