1. 程式人生 > 其它 >【DOM】JavaScript DOM-事件基礎-節點操作-屬性操作-建立元素-增刪改查

【DOM】JavaScript DOM-事件基礎-節點操作-屬性操作-建立元素-增刪改查

技術標籤:JavaScript高階javascriptjs

文章目錄

1. DOM

1.1 DOM簡介

文件物件模型(Document Object Model,簡稱 DOM),是 W3C 組織推薦的處理可擴充套件標記語言(HTML或者XML)的標準程式設計介面。

W3C 已經定義了一系列的 DOM 介面,通過這些 DOM 介面可以改變網頁的內容、結構和樣式。

1.2 DOM樹

image

  • 文件:一個頁面就是一個文件,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 事件三要素

  1. 事件源————事件被觸發的物件
  2. 事件型別————如何觸發 什麼事件(滑鼠點選、經過、鍵盤按下)
  3. 事件處理程式————通過函式賦值完成

3.2 執行事件步驟

  1. 獲取事件源
  2. 註冊事件(繫結事件)
  3. 新增事件處理程式
var btn = document.getElementById('btn');
btn.onclick = function() {
  alert('你好嗎');  
};

3.3 常見滑鼠事件

滑鼠事件觸發條件
onclick滑鼠點選左鍵觸發
onmouseover滑鼠經過觸發
onmoouseout滑鼠離開觸發
onfocus獲得滑鼠焦點觸發
onblur失去滑鼠焦點觸發
onmousemove滑鼠移動觸發
onmouseup滑鼠彈起觸發
onmousedowm滑鼠按下觸發

4. 操作元素

4.1 改變元素內容

  1. 從起始到終止位置,但它去除html標籤,同時空格和換行也去掉
element.innerText
  1. 從起始到終止位置,包括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 // 類名樣式操作
  • 注意
  1. JS 裡面的樣式採取駝峰命名法 比如 fontSize、 backgroundColor
  2. JS 修改 style 樣式操作,產生的是行內樣式,CSS 權重比較高
  3. 如果樣式修改較多,可以採取操作類名方式更改元素樣式
  4. class因為是個保留字,因此使用className來操作元素類名屬性
  5. 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 元素(節點)均可被修改,也可以建立或刪除。

image

  • 一般地,節點至少擁有nodeType(節點型別)、nodeName(節點名稱)和nodeValue(節點值)這三個基本屬性。
  1. 元素節點 nodeType 為 1
  2. 屬性節點 nodeType 為 2
  3. 文字節點 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() 方法返回呼叫該方法的節點的一個副本。

  • 也稱為克隆節點/拷貝節點

  • 注意:

  1. 如果括號引數為空或者為 false則是淺拷貝,即只克隆複製節點本身,不克隆裡面的子節點。
  2. 如果括號引數為 true ,則是深度拷貝,會複製節點本身以及裡面所有的子節點。

5.7 三種動態建立元素區別

document.write()
element.innerHTML
document.createElement()
  1. document.write 是直接將內容寫入頁面的內容流,但是文件流執行完畢,則它會導致頁面全部重繪
  2. innerHTML 是將內容寫入某個 DOM 節點,不會導致頁面全部重繪
  3. innerHTML 建立多個元素效率更高(不要拼接字串,採取陣列形式拼接),結構稍微複雜
  4. createElement() 建立多個元素效率稍低一點點,但是結構更清晰
  • 總結:不同瀏覽器下,innerHTML 效率要比 creatElement 高

6. 總結

  • 文件物件模型(Document Object Model,簡稱 DOM),是 W3C 組織推薦的處理可擴充套件標記語言(HTML或者XML)的標準程式設計介面。
  • W3C 已經定義了一系列的 DOM 介面,通過這些 DOM 介面可以改變網頁的內容、結構和樣式。
  1. 對於JavaScript,為了能夠使JavaScript操作HTML,JavaScript就有了一套自己的dom程式設計介面。
  2. 對於HTML,dom使得html形成一棵dom樹. 包含 文件、元素、節點
  • 我們獲取過來的DOM元素是一個物件(object),所以稱為 文件物件模型

  • 關於dom操作,我們主要針對於元素的操作。主要有建立、增、刪、改、查、屬性操作、事件操作。

6.1 建立

  1. document.write
  • 如果頁面文件載入完畢,再呼叫它會導致頁面重繪
  1. innerHTML
  2. createElement

6.2 增

  1. appendChild
  2. insertBefore

6.3 刪

  1. removeChild

6.4 改

  • 主要修改dom的元素屬性,dom元素的內容、屬性, 表單的值等
  • 修改元素屬性: src、href、title等
  • 修改普通元素內容: innerHTML 、innerText
  • 修改表單元素: value、type、disabled等
  • 修改元素樣式: style、className

6.5 查

  • 主要獲取查詢dom的元素
  1. DOM提供的API方法
  • getElementById、
  • getElementsByTagName
  • 古老用法 不太推薦
  1. H5提供的新方法
  • querySelector、
  • querySelectorAll
  • 提倡
  1. 利用節點操作獲取元素
  • 父(parentNode)
  • 子(children)
  • 兄(previousElementSibling、nextElementSibling)
  • 提倡

6.6 屬性操作

  • 主要針對於自定義屬性。
  1. setAttribute:設定dom的屬性值
  2. getAttribute:得到dom的屬性值
  3. removeAttribute移除屬性

6.7 事件操作

給元素註冊事件

事件源.事件型別 = 事件處理程式