【DOM】JavaScript DOM-事件基礎-節點操作-屬性操作-建立元素-增刪改查
阿新 • • 發佈:2021-01-08
文章目錄
- 1. DOM
- 2. 獲取元素
- 3. 事件基礎
- 4. 操作元素
- 4.5 自定義屬性的操作
- 4.6 H5自定義屬性
- 5 節點操作
- 6. 總結
1. DOM
1.1 DOM簡介
文件物件模型(Document Object Model,簡稱 DOM),是 W3C 組織推薦的處理可擴充套件標記語言(HTML或者XML)的標準程式設計介面。
W3C 已經定義了一系列的 DOM 介面,通過這些 DOM 介面可以改變網頁的內容、結構和樣式。
1.2 DOM樹
- 文件:一個頁面就是一個文件,DOM 中使用 document 表示
- 元素:頁面中的所有標籤都是元素,DOM 中使用 element 表示
- 節點:網頁中的所有內容都是節點(標籤、屬性、文字、註釋等),DOM 中使用 node 表示
DOM 把以上內容都看做是物件
2. 獲取元素
2.1 經典
2.1.1 getElementById
document.getElementById('id');
2.1.2 getElementsByTagName
document.getElementsByTagName('標籤名');
- 因為得到的是一個物件的集合,所以我們想要操作裡面的元素就需要遍歷。
- 得到元素物件是動態的
- 如果獲取不到元素,則返回為空的偽陣列(因為獲取不到物件)
2.2 HTML5新增
2.2.1 getElementsByClassName
document.getElementsByClassName(‘類名’); // 根據類名返回元素物件集合
2.2.2 querySelector
document.querySelector('選擇器'); // 根據指定選擇器返回第一個元素物件
2.2.3 querySelectorAll
document.querySelectorAll('選擇器'); // 根據指定選擇器返回
2.3 body&html
2.3.1 document.body
document.body; // 返回 body元素物件
2.3.2 document.documentElement
document.documentElement; // 返回 html元素物件
3. 事件基礎
3.1 事件三要素
- 事件源————事件被觸發的物件
- 事件型別————如何觸發 什麼事件(滑鼠點選、經過、鍵盤按下)
- 事件處理程式————通過函式賦值完成
3.2 執行事件步驟
- 獲取事件源
- 註冊事件(繫結事件)
- 新增事件處理程式
var btn = document.getElementById('btn');
btn.onclick = function() {
alert('你好嗎');
};
3.3 常見滑鼠事件
滑鼠事件 | 觸發條件 |
---|---|
onclick | 滑鼠點選左鍵觸發 |
onmouseover | 滑鼠經過觸發 |
onmoouseout | 滑鼠離開觸發 |
onfocus | 獲得滑鼠焦點觸發 |
onblur | 失去滑鼠焦點觸發 |
onmousemove | 滑鼠移動觸發 |
onmouseup | 滑鼠彈起觸發 |
onmousedowm | 滑鼠按下觸發 |
4. 操作元素
4.1 改變元素內容
- 從起始到終止位置,但它去除html標籤,同時空格和換行也去掉
element.innerText
- 從起始到終止位置,包括html標籤,同時保留空格和換行
element.innerHTML
4.2 改變元素屬性
- innerText、innerHTML 改變元素內容
- src、href
- id、alt、title
4.3 表單元素的屬性操作
- type、value、checked、selected、disabled
4.4 樣式屬性操作
4.4.1 element.style
element.style // 行內樣式操作
4.4.2 element.className
element.className // 類名樣式操作
- 注意
- JS 裡面的樣式採取駝峰命名法 比如 fontSize、 backgroundColor
- JS 修改 style 樣式操作,產生的是行內樣式,CSS 權重比較高
- 如果樣式修改較多,可以採取操作類名方式更改元素樣式
- class因為是個保留字,因此使用className來操作元素類名屬性
- className 會直接更改元素的類名,會覆蓋原先的類名
4.5 自定義屬性的操作
4.5.1 獲取屬性值
element.屬性 獲取屬性值。
element.getAttribute('屬性');
區別
- element.屬性 獲取內建屬性值(元素本身自帶的屬性)
- element.getAttribute(‘屬性’); 主要獲得自定義的屬性 (標準) 我們程式設計師自定義的屬性
4.5.2 設定屬性值
element.屬性 = '值' // 設定內建屬性值
element.setAttribute('屬性', '值');
區別
- element.屬性 設定內建屬性值
- element.setAttribute(‘屬性’); 主要設定自定義的屬性 (標準)
4.5.3 移除屬性
element.removeAttribute('屬性');
4.6 H5自定義屬性
自定義屬性目的:是為了儲存並使用資料。有些資料可以儲存到頁面中而不用儲存到資料庫中。
自定義屬性獲取是通過getAttribute(‘屬性’) 獲取。
但是有些自定義屬性很容易引起歧義,不容易判斷是元素的內建屬性還是自定義屬性。所以H5做了一些新的規定
4.6.1 設定H5自定義屬性
- H5規定自定義屬性data-開頭做為屬性名並且賦值。
<div data-index='1'></div>
element.setAttribute('data-index', 2)
4.6.2 獲取H5自定義屬性
4.6.2.1 相容性獲取
element.getAttribute('data-index');
4.6.2.2 H5新增 (IE11+ )
element.dataset.index;
element.dataset['index']; // ie 11才開始支援
dataset 是一個集合,裡面存放了所有以data開頭的自定義屬性
<div getTime="20" data-index="2" data-list-name="andy"></div>
<script>
var div = document.querySelector('div');
// console.log(div.getTime); // undefined
console.log(div.getAttribute('getTime'));
div.setAttribute('data-time', 20);
console.log(div.getAttribute('data-index'));
console.log(div.getAttribute('data-list-name'));
// h5新增的獲取自定義屬性的方法 它只能獲取data-開頭的
// dataset 是一個集合裡面存放了所有以data開頭的自定義屬性
console.log(div.dataset);
console.log(div.dataset.index);
console.log(div.dataset['index']);
// 如果自定義屬性裡面有多個-連結的單詞,我們獲取的時候採取 駝峰命名法
console.log(div.dataset.listName);
console.log(div.dataset['listName']);
</script>
5 節點操作
5.1 獲取元素通常使用兩種方式
5.1.1 利用 DOM 提供的方法獲取元素
- document.getElementById()
- document.getElementsByTagName()
- document.querySelector 等
- 邏輯性不強、繁瑣
5.1.2 利用節點層級關係獲取元素
- 利用父子兄節點關係獲取元素
- 邏輯性強, 但是相容性稍差
這兩種方式都可以獲取元素節點,我們後面都會使用,但是節點操作更簡單
5.2 節點概述
- 網頁中的所有內容都是節點(標籤、屬性、文字、註釋等),在DOM 中,節點使用 node 來表示。
- HTML DOM 樹中的所有節點均可通過 JavaScript 進行訪問,所有 HTML 元素(節點)均可被修改,也可以建立或刪除。
- 一般地,節點至少擁有nodeType(節點型別)、nodeName(節點名稱)和nodeValue(節點值)這三個基本屬性。
- 元素節點 nodeType 為 1
- 屬性節點 nodeType 為 2
- 文字節點 nodeType 為 3 (文字節點包含文字、空格、換行等)
- 我們在實際開發中,節點操作主要操作的是元素節點
5.3 節點層級
- 利用 DOM 樹可以把節點劃分為不同的層級關係,常見的是父子兄層級關係。
5.3.1 父級節點 parentNode
node.parentNode
- parentNode 屬性可返回某節點的父節點,注意是最近的一個父節點
- 如果指定的節點沒有父節點則返回 null
5.3.2 子節點
childNodes
1. parentNode.childNodes(標準)
- parentNode.childNodes 返回包含指定節點的子節點的集合,該集合為即時更新的集合。
- 注意:返回值裡面包含了所有的子節點,包括元素節點,文字節點等。
- 如果只想要獲得裡面的元素節點,則需要專門處理。
- 所以我們一般不提倡使用childNodes
var ul = document. querySelector(‘ul’);
for(var i = 0; i < ul.childNodes.length;i++) {
if (ul.childNodes[i].nodeType == 1) {
// ul.childNodes[i] 是元素節點
console.log(ul.childNodes[i]);
}
}
children
parentNode.children(非標準)
- parentNode.children 是一個只讀屬性,返回所有的子元素節點
- 它只返回子元素節點,其餘節點不返回 (這個是我們重點掌握的)
- 雖然children 是一個非標準,但是得到了各個瀏覽器的支援,因此我們可以放心使用
firstChild
parentNode.firstChild
- firstChild 返回第一個子節點,找不到則返回null
- 同樣,也是包含所有的節點
lastChild
parentNode.lastChild
- lastChild 返回最後一個子節點,找不到則返回null
- 同樣,也是包含所有的節點。
firstElementChild
parentNode.firstElementChild
- firstElementChild 返回第一個子元素節點,找不到則返回null
lastElementChild
parentNode.lastElementChild
- lastElementChild 返回最後一個子元素節點,找不到則返回null。
注意:這兩個方法有相容性問題,IE9 以上才支援。
實際開發
-
實際開發中,firstChild 和 lastChild 包含其他節點,操作不方便,而 firstElementChild 和 lastElementChild 又有相容性問題,那麼我們如何獲取第一個子元素節點或最後一個子元素節點呢?
-
解決方案:
-
如果想要第一個子元素節點,可以使用
parentNode.chilren[0]
- 如果想要最後一個子元素節點,可以使用
parentNode.chilren[parentNode.chilren.length - 1]
5.3.3 兄弟節點
nextSibling
node.nextSibling
- nextSibling 返回當前元素的下一個兄弟元素節點,找不到則返回null。
- 同樣,也是包含所有的節點。
previousSibling
node.previousSibling
- previousSibling 返回當前元素上一個兄弟元素節點,找不到則返回null。
- 同樣,也是包含所有的節點。
nextElementSibling
node.nextElementSibling
- nextElementSibling 返回當前元素下一個兄弟元素節點,找不到則返回null。
previousElementSibling
node.previousElementSibling
- previousElementSibling 返回當前元素上一個兄弟節點,找不到則返回null。
- 注意:這兩個方法有相容性問題, IE9 以上才支援。
解決相容性問題
問:如何解決相容性問題 ?
答:自己封裝一個相容性的函式
function getNextElementSibling(element) {
var el = element;
while (el = el.nextSibling) {
if (el.nodeType === 1) {
return el;
}
}
return null;
}
5.4 建立節點
document.createElement('tagName')
- document.createElement() 方法建立由 tagName 指定的 HTML 元素
- 因為這些元素原先不存在,是根據我們的需求動態生成的,所以我們也稱為動態建立元素節點
5.5 新增節點
appendChild
node.appendChild(child)
- node.appendChild() 方法將一個節點新增到指定父節點的子節點列表末尾
- 類似於 CSS 裡面的 after 偽元素
- 類似於陣列的push
insertBefore
node.insertBefore(child, 指定元素)
- node.insertBefore() 方法將一個節點新增到父節點的指定子節點前面
- 類似於 CSS 裡面的 before 偽元素
5.5 刪除節點 removeChild
node.removeChild(child)
- node.removeChild() 方法從 DOM 中刪除一個子節點,返回刪除的節點。
5.6 複製節點(克隆節點) cloneNode
node.cloneNode()
-
node.cloneNode() 方法返回呼叫該方法的節點的一個副本。
-
也稱為克隆節點/拷貝節點
-
注意:
- 如果括號引數為空或者為 false則是淺拷貝,即只克隆複製節點本身,不克隆裡面的子節點。
- 如果括號引數為 true ,則是深度拷貝,會複製節點本身以及裡面所有的子節點。
5.7 三種動態建立元素區別
document.write()
element.innerHTML
document.createElement()
- document.write 是直接將內容寫入頁面的內容流,但是文件流執行完畢,則它會導致頁面全部重繪
- innerHTML 是將內容寫入某個 DOM 節點,不會導致頁面全部重繪
- innerHTML 建立多個元素效率更高(不要拼接字串,採取陣列形式拼接),結構稍微複雜
- createElement() 建立多個元素效率稍低一點點,但是結構更清晰
- 總結:不同瀏覽器下,innerHTML 效率要比 creatElement 高
6. 總結
- 文件物件模型(Document Object Model,簡稱 DOM),是 W3C 組織推薦的處理可擴充套件標記語言(HTML或者XML)的標準程式設計介面。
- W3C 已經定義了一系列的 DOM 介面,通過這些 DOM 介面可以改變網頁的內容、結構和樣式。
- 對於JavaScript,為了能夠使JavaScript操作HTML,JavaScript就有了一套自己的dom程式設計介面。
- 對於HTML,dom使得html形成一棵dom樹. 包含 文件、元素、節點
-
我們獲取過來的DOM元素是一個物件(object),所以稱為 文件物件模型
-
關於dom操作,我們主要針對於元素的操作。主要有建立、增、刪、改、查、屬性操作、事件操作。
6.1 建立
- document.write
- 如果頁面文件載入完畢,再呼叫它會導致頁面重繪
- innerHTML
- createElement
6.2 增
- appendChild
- insertBefore
6.3 刪
- removeChild
6.4 改
- 主要修改dom的元素屬性,dom元素的內容、屬性, 表單的值等
- 修改元素屬性: src、href、title等
- 修改普通元素內容: innerHTML 、innerText
- 修改表單元素: value、type、disabled等
- 修改元素樣式: style、className
6.5 查
- 主要獲取查詢dom的元素
- DOM提供的API方法
- getElementById、
- getElementsByTagName
- 古老用法 不太推薦
- H5提供的新方法
- querySelector、
- querySelectorAll
- 提倡
- 利用節點操作獲取元素
- 父(parentNode)
- 子(children)
- 兄(previousElementSibling、nextElementSibling)
- 提倡
6.6 屬性操作
- 主要針對於自定義屬性。
- setAttribute:設定dom的屬性值
- getAttribute:得到dom的屬性值
- removeAttribute移除屬性
6.7 事件操作
給元素註冊事件
事件源.事件型別 = 事件處理程式