還沒搞懂 JavaScript DOM 嗎 進來看看吧

什麼是 DOM

文檔對象模型 ( Document Object Model ) 是 HTML 和 XML 文檔的編程接口。它提供了對文檔的結構化的表述,並定義了一種方式可以從程序中對該結構進行訪問,從而改變文檔的結構,樣式和內容。DOM 將文檔解析爲一個由節點和對象 ( 包含屬性和方法 ) 組成的結構集合。簡言之,它會將 WEB 頁面和腳本或程序語言來連接起來

一個 WEB 頁面是一個文檔,這個文檔可以在瀏覽器窗口或作爲 HTML 源碼顯示出來。但上述兩個情況中都是同一份文檔,文檔對象模型 ( DOM ) 提供了對同一份文檔的另一種表現,存儲和操作的方式。DOM 是 WEB 頁面的完全面向對象的表述,它能夠使用如 JavaScript 等腳本語言進行修改

什麼是 HTML DOM

HTML DOM 是 HTML 的標準對象模型和編程接口,它定義了:

  • 作爲對象的 HTML 元素
  • 所有 HTML 元素的屬性
  • 訪問所有 HTML 元素的方法
  • 所有 HTML 元素的事件

在這裏插入圖片描述

通過這個對象模型,JavaScript 可以獲得創建動態 HTML 的所有力量:

  • JavaScript 能改變頁面中的所有 HTML 元素
  • JavaScript 能改變頁面中的所有 HTML 屬性
  • JavaScript 能改變頁面中的所有 CSS 樣式
  • JavaScript 能刪除已有的 HTML 元素和屬性
  • JavaScript 能添加新的 HTML 元素和屬性
  • JavaScript 能對頁面中所有已有的 HTML 事件作出反應
  • JavaScript 能在頁面中創建新的 HTML 事件

DOM 操作

HTML DOM 節點

在 HTML DOM 中,每一個元素都是 節點

  • 文檔是一個文檔節點
  • 所有的 HTML 元素都是元素節點
  • 所有的 HTML 屬性都是屬性節點
  • 文本插入到 HTML 元素是文本節點
  • 註釋是註釋節點

Document 對象

當瀏覽器載入 HTML 文檔,它就會成爲 Document 對象
Document 對象是 HTML 文檔的根節點
Document 對象使我們可以從腳本中對 HTML 頁面中的所有元素進行訪問

常用屬性

屬性 描述
document.activeElement 返回當前獲取焦點元素
document.cookie 設置或返回與當前文檔有關的所有cookie
document.body 返回當前文檔的 body 元素
document.baseURL 返回文檔的絕對基礎URL
document.documentElement 返回文檔根節點
document.domain 返回當前文檔的域名
document.forms 返回當前文檔中所有 Form 對象引用
document.images 返回當前文檔中所有 image 對象引用
document.links 返回文檔中所有鏈接對象引用
document.head 返回文檔 head 元素
document.referrer 返回載入當前文檔的文檔URL
document.title 返回當前文檔的標題
document.URL 返回文檔完整URL
document.readyState 返回當前文檔加載狀態
document.characterSet 返回當前文檔使用的字符集

獲取元素

(1) 通過 id屬性 獲取元素對象

返回值爲 元素對象

var oDiv = document.getElementById("id值");

(2) 通過 標籤名字 獲取元素對象

返回值爲 元素數組

var oDiv = document.getElementsByTagName("標籤名");

(3) 通過 class屬性 獲取元素對象

返回值爲 元素數組

var oDiv = document.getElementsByClassName("class值")

(4) 通過 name值 獲取元素對象

返回值爲 元素數組

var oDiv = document.getElementsByName("name值")

(5) 通過 CSS選擇器 獲取元素對象

# 返回文檔中匹配 CSS選擇器 的第一個元素
document.querySelector("CSS選擇器")

# 返回文檔中匹配 CSS選擇器 的所有元素
document.querySelectorAll("CSS選擇器");

Element對象

元素對象 ( Element ) 代表着一個 HTML 元素
元素對象的 子節點 可以是 元素節點,文本節點,註釋節點

基本屬性

屬性 描述
element.attributes 返回元素的屬性數組
element.offsetHeight 返回元素的高度(包括border和padding)
element.offsetWidth 返回元素的寬度(包括border和padding)
element.offsetLeft 返回元素距離父元素左側的距離(父元素需要具備定位屬性)
element.offsetTop 返回元素距離父元素頂部的距離(父元素需要具備定位屬性)

屬性修改

函數 描述
element.hasAttributes() 判斷元素是否具有屬性
element.hasAttribute(attr) 判斷元素是否具有指定屬性
element.setAttribute(attr,value) 給元素設置屬性
element.getAttribute(attr) 獲取指定屬性
element.removeAttribute(attr) 刪除指定屬性

節點操作

屬性 描述
element.children 返回元素子元素節點
element.firstElementChild 返回元素第一個元素節點
element.lastElementChild 返回元素最後一個元素點
element.previousElementSibling 返回元素上一個兄弟元素
element.nextElementSibling 返回元素下一個兄弟元素
element.parentNode 返回元素父節點
element.hasChildNodes() 判斷元素是否具有子元素

樣式操作

1. element.style 讀取/修改樣式

// 獲取元素對象
var div = document.getElementById("div");
// 獲取樣式
console.log(div.style.backgroundColor)
// 修改樣式
div.style.backgroundColor = "red";

2. getComputedStyle 獲取樣式

// 獲取元素對象的 CSS樣式 數組
var style = window.getComputedStyle(元素對象[,"僞類"]);
console.log(style);

兩者區別

  • 只讀和讀寫

    • getComputedStyle 方法是隻讀的,只能獲取樣式,不能設置;
    • element.style 能讀能寫
  • 獲取屬性的範圍

    • getComputedStyle 方法獲取的是最終應用在元素上的所有 CSS屬性對象;
    • element.style 只能獲取 style 屬性中的 CSS樣式。

對於一個光禿禿的元素 <p>element.style在獲取樣式方面就不如 getComputedStyle 方法了!

文本操作

屬性 描述
element.innerHTML 設置和查看標籤內容,包含 HTML 格式
element.innerText 設置和查看標籤內容,僅支持純文本內容

元素/節點 增刪

創建標籤

var btu = document.createElement("button");

創建文本節點

var text = document.createTextNode("hello");

克隆節點

cloneNode(deep) 克隆一個節點,deep 設置爲 true 將遞歸克隆內部節點

// 獲取 div 元素
var div = div.insertBefore(h1,div.firstChild);
// 克隆 div 元素
var new_div = div.cloneNode()

添加節點

appendChild(node) 添加一個節點到末尾

// 創建一個 h1 標籤
var h1 = document.createElement("h1");
// 創建一個 文本節點
var text = document.createTextNode("hello");

// 將 文本節點 添加到 h1標籤中
h1.appendChild(text);

插入節點
insertBefore(new_node,old_node) 插入一個節點到某個節點之前

// 創建一個 h1 標籤
var h1 = document.createElement("h1");
// 獲取 div 元素
var div = document.getElementById("item");

// 插入 h1 標籤到父節點第一個位置
div.insertBefore(h1,div.firstChild);

刪除節點

removeChild(node) 刪除一個子節點

// 獲取 div 元素
var div = document.getElementById("item");

// 刪除 div 元素最後一個子節點
div.removeChild(div.lastChild)

事件

事件是 JavaScript 與 HTML 交互的基礎,要實現用戶與頁面的交互,先要對目標元素綁定特定的事件,設置事件處理函數,然後用戶觸發事件,事件處理函數執行,產生交互效果

事件類型

在 HTML DOM 中有兩種事件傳播的方法:冒泡和捕獲

事件傳播是一種定義當發生事件時元素次序的方法,假如 <div> 元素內有一個 <p>,然後用戶點擊了這個 <p> 元素,應該首先傳遞哪個元素的 click 事件?

在冒泡中,最內側元素的事件會首先處理,然後是更外側的:首先處理 <p> 元素的點擊事件,然後是 <div> 元素的點擊事件
在捕獲中,最外側元素的事件會首先被處理,然後是更內側的:首先處理 <div> 元素的點擊事件,然後是 <p> 元素的點擊事件

綁定事件

(1) DOM 0級事件

<button id="btu">提交</button>
<script>
    var btu = document.getElementById("btu");

    // 綁定事件
    btu.onclick = function(){
        console.log("hello!");
    };

    // 解綁事件
    btu.onclick = null;
</script>

缺點:無法設置多個事件處理函數

(2) DOM 2級事件

<button id="btu">提交</button>
<script>
    var btu = document.getElementById("btu");

    // 綁定事件
    btu.addEventListener("click",showFn,false);
    btu.addEventListener("click",showFn2,false);

    function showFn(){
        console.log("hello fn1");
    };

    function showFn2(){
        console.log("hello fn2");
    }

    // 解綁事件
    btn.removeEventListener("click",showFn,false);
</script>

可以爲元素綁定多個事件處理函數,可以通過第三個參數設置事件類型,默認爲 false,將使用冒泡傳播,如果設置爲 true,則爲捕獲傳播

Event 對象常見應用

(1) event.preventDefault()

如果調用這個方法,元素默認事件行爲將不再觸發。
什麼是默認事件呢?例如表單 點擊提交按鈕跳轉頁面,a標籤默認頁面跳轉或是錨點定位等

很多時候我們使用 a標籤僅僅是想當做一個普通的按鈕,點擊實現一個功能,不想頁面跳轉

<a id="test" href="http://www.cnblogs.com">鏈接</a>
<script>
var a = document.getElementById("test");
// 此時,點擊a標籤只會打印消息,而不會進行頁面跳轉
a.onclick = function(e){
    console.log("點擊了a標籤");
    e.preventDefault();
}
</script>

(2) event.stopPropagation()

阻止事件冒泡到父元素

前邊提到事件冒泡是指事件從目標節點自下而上向 window對象傳播的階段,添加 event.stopPropagation() 這句話後,就阻止了父事件的執行

(3) event.stopImmediatePropagation();

即能阻止事件向父元素冒泡,也能阻止元素同事件類型的其它監聽器被觸發

例如,一個按鈕元素綁定了多個 click 事件,當在某個 click() 事件中添加了 event.stopImmediatePropagation(); 後,不僅阻止了父事件的執行,還阻止了其它 click 事件的執行

事件代理

由於事件會在冒泡階段向上傳播到父節點,因此可以把子節點的監聽函數定義在父節點上,由父節點的監聽函數統一處理多個子元素的事件,這種方法叫做事件的代理(delegation)

優點:

  1. 減少內存消耗,提高性能

假設有一個列表,列表之中有大量的列表項,我們需要在點擊每個列表項的時候響應一個事件

如果給每個列表項一一綁定一個函數,那對於內存的消耗是非常龐大的,效率上需要消耗很多性能,藉助事件代理,我們只需要給父容器 ul 綁定方法即可,這樣不管點擊的是哪一個後代元素,都會根據冒泡傳播的傳遞機制,把容器的 click行爲觸發,然後把對應的方法執行,根據事件源,我們可以知道點擊的是誰,從而完成不同的事

  1. 動態綁定事件

很多時候,我們需要動態的增刪列表項元素,如果一開始給每個子元素綁定事件,那麼在列表發生變化時,就需要重新給新增的元素綁定事件,給即將刪除的元素解綁事件,如果用事件代理就會省去很多這樣的麻煩!

常用事件速查手冊

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章