JavaScript DOM

DOM簡介

  • DOM(文檔對象模型) 是一項 W3C標準。
  • DOM 模型被結構化爲對象樹。
  • DOM 本質:從html文件提取出個一棵樹。
  • DOM 是關於如何獲取、更改、添加或刪除 HTML 元素的標準。

Document 對象html

文檔對象表明您的網頁。訪問 HTML 頁面中的任何元素,老是從訪問 document 對象開始。

DOM 節點

根據 W3C HTML DOM 標準,HTML 文檔中的全部事物都是節點:node

  • 整個文檔是文檔節點
  • 每一個 HTML 元素是元素節點
  • HTML 元素內的文本是文本節點
  • 每一個 HTML 屬性是屬性節點
  • 全部註釋是註釋節點

節點關係

父(parent)、子(child)和同胞(sibling)用於描述這些關係。
在節點之間導航
經過 JavaScript,您可使用如下節點屬性在節點之間導航:數組

  • parentNode
  • childNodes[nodenumber]
  • firstChild
  • lastChild
  • nextSibling
  • previousSibling

子節點和節點值

DOM 處理中的一種常見錯誤是認爲元素節點中包含文本。而應該是元素節點包含了文本節點。
獲取文本節點的值瀏覽器

  • 能夠經過節點的 innerHTML 屬性進行訪問。
  • 也能夠訪問首個子節點的 nodeValue
<title id="demo">DOM 教程</title> 
<script>
//方法一
let myTitle = document.getElementById("demo").innerHTML;
//方法二
let myTitle = document.getElementById("demo").firstChild.nodeValue;
//方法三
let myTitle = document.getElementById("demo").childNodes\[0\].nodeValue;
</script>

DOM 根節點

有兩個特殊屬性容許訪問完整文檔:
document.body:文檔的 body
document.documentElement:檔的html(完整文檔)緩存

DOM 節點屬性

nodeName 屬性cookie

規定節點的名稱。只讀。老是包含 HTML 元素的大寫標籤名。
  • 元素節點的 nodeName 等同於標籤名
  • 屬性節點的 nodeName 是屬性名稱
  • 文本節點的 nodeName 老是 #text
  • 文檔節點的 nodeName 老是 #document

nodeValue 屬性app

規定節點的值。可寫。
  • 元素節點的 nodeValue 是 undefined
  • 文本節點的 nodeValue 是文本文本
  • 屬性節點的 nodeValue 是屬性值

nodeType 屬性性能

返回節點的類型。只讀。

DOM 節點操做

查找 HTML 元素

經過 id 查找 HTML 元素spa

//查找 id="intro" 的元素:
let myElement = document.getElementById("intro");

經過標籤名查找 HTML 元素代理

//查找 id="main" 的元素,而後查找 "main" 中全部 <p> 元素:
let x = document.getElementById("main");
let y = x.getElementsTagName("p");

經過類名查找 HTML 元素

//返回包含 class="intro" 的全部元素的列表:
let x = document.getElementsByClassName("intro");

經過 CSS 選擇器查找 HTML 元素

須要查找匹配指定 CSS 選擇器(id、類名、類型、屬性、屬性值等等)的全部 HTML 元素,請使用 querySelectorAll() 方法。
//返回 class="intro" 的全部 <p> 元素列表:
let x = document.querySelectorAll("p.intro");

經過 HTML 對象集合查找 HTML 元素

//查找 id="frm1" 的 form 元素,在 forms 集合中,而後顯示全部元素值:
let x = document.forms["frm1"];
let text = "";
for(let i = 0; i<x.length;i++){
    text += x.elements[i],value+"<br>";
}
document.getElementById("demo").innerHTML = text;
屬性 描述 DOM
document.anchros 返回擁有 name 屬性的全部 元素。 1
document.body 返回<body>元素 1
document.cookie 返回文檔的 cookie 1
document.forms 返回全部 <form> 元素 1
document.images 返回全部 <img> 元素 1
document.title 返回 <title> 元素 1
document.documentElement 返回 <html> 元素 3
document.head 返回 <head> 元素 3
document.scripts 返回全部 <script> 元素 3

改變 HTML

改變 HTML 輸出流
document.write() 可用於直接寫入 HTML 輸出流:千萬不要在文檔加載後使用 document.write()。這麼作會覆蓋文檔。
改變 HTML 內容
使用 innerHTML 屬性。

document.getElementById(id).innerHTML = 'new text'

改變屬性的值

document.getElementById("myImage").src = "landscape.jpg";

改變 CSS

語法:
**document.getElementById(id).style.property = new style
**

document.getElementById("p2").style.color = "blue";

attribute 和 property 的區別
property:修改對象屬性,不會體現到html結構中, DOM中的屬性,是JavaScript裏的對象。(推薦)
attribute:修改html屬性,會改變html結構,HTML標籤上的特性,它的值只可以是字符串。
二者都有可能引發DOM從新渲染。
DOM對象初始化時會在建立默認的基本property。

DOM 結構操做

如需向 HTML DOM 添加新元素,您必須首先建立這個元素(元素節點),而後將其追加到已有元素。

添加新 HTML 元素(節點)

建立新 HTML 元素(節點)

document.createElement("p");
document.createTextNode("這是新文本。");

追加到已有元素

para.appendChild(node);//追加新元素做爲父的最後一個子。
element.insertBefore(para, child);//將para插入到父元素element下的child子元素前面

示例:

<div id="div1">
    <p id="p1">這是一個段落。</p>
    <p id="p2">這是另外一個段落。</p>
</div>
<script>
    var para = document.createElement("p");
    var node = document.createTextNode("這是新文本。");
    para.appendChild(node);
    var element = document.getElementById("div1");
    element.appendChild(para);
</script>

刪除已有 HTML 元素

如需刪除某個 HTML 元素,您須要知曉該元素的父節點。
常見的方法:找到你想要刪除的子節點,並利用其 parentNode 屬性找到父節點。

示例:

<div id="div1">
<p id="p1">這是一個段落。</p>
<p id="p2">這是另外一個段落。</p>
</div>
<script>
//方法一
    let parent = document.getElementById("div1");
    let child = document.getElementById("p1");
    parent.removeChild(child);

//方法二
    let child = document.getElementById("p1");
    child.parentNode.removeChild(child);
</script>

替換 HTML 元素

如需替換元素的,請使用 replaceChild() 方法。

<div id="div1">
    <p id="p1">這是一個段落。</p>
    <p id="p2">這是另外一個段落。</p>
</div>

<script>
    let para = document.createElement("p");
    let node = document.createTextNode("這是新文本。");
    para.appendChild(node);

    let parent = document.getElementById("div1");
    let child = document.getElementById("p1");
    parent.replaceChild(para, child);
</script>

DOM 集合與節點列表

DOM集合:HTMLCollection 對象

HTMLCollection 對象是類數組的 HTML 元素列表(集合)。但它並不是是數組。沒法對 HTMLCollection 使用數組方法,好比 valueOf()、pop()、push() 或 join()。
length 屬性定義了 HTMLCollection 中元素的數量。
getElementsByTagName() 方法返回 HTMLCollection 對象。

//下面的代碼選取文檔中的全部 <p> 元素:
var x = document.getElementsByTagName("p");

DOM 節點列表:NodeList 對象

NodeList 對象是從文檔中提取的節點列表(集合)。NodeList 對象與 HTMLCollection 對象幾乎相同。
全部瀏覽器都會爲 childNodes 屬性返回 NodeList 對象。
大多數瀏覽器會爲 querySelectorAll() 方法返回 NodeList 對象。

HTMLCollection 與 NodeList 的區別

  • HTMLCollection是 HTML 元素的集合。NodeList 是文檔節點的集合(元素節點+包含屬性節點和文本節點)。
  • 訪問 HTMLCollection 項目,能夠經過它們的名稱、id 或索引號。訪問 NodeList 項目,只能經過它們的索引號。

DOM 性能

避免頻繁的DOM操做:

採用事件代理避免了頻繁的操做DOM

將頻繁操做改成一次性操做

let pList = document.getElementsByClassName("para");
let frag = document.createDocumentFragment();
for (let i = 0; i < 5; i++) {
    let span = document.createElement("span");
    span.innerHTML = `${i}`;
    frag.appendChild(span);
}
pList[0].appendChild(frag);

對DOM查詢作緩存

// 不緩存DOM查詢結果
for (let i = 0; i < document.getElementsByTagName('p').length; i++) {
    //每次循環,都會計算 length ,頻繁進行DOM 查詢
}
const pList = document.getElementsByTagName('p');
const length = pList.length;
for (let i = 0; i < length; i++) {
    //緩存length,只進行一次DOM查詢
}
相關文章
相關標籤/搜索