js基礎篇(三)——DOM的各種操作

1. 什么是DOM

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

HTML DOM樹

2.DOM節點

在 HTML DOM (Document Object Model) 中 , 每一個元素都是** 節點**:

  • 整個html文檔就是是一個Document
  • 所有的HTML元素都是元素節點。
  • 所有 HTML 屬性都是屬性節點。
  • 文本插入到 HTML 元素是文本節點。
  • 注釋是注釋節點。

3. Document 對象

  • 當瀏覽器載入 HTML 文檔, 它就會成為 document對象。
  • document 對象是HTML文檔的根節點與所有其他節點(元素節點,文本節點,屬性節點, 注釋節點)。
  • Document對象使我們可以從腳本中對 HTML 頁面中的所有元素進行訪問。
    ** 提示:**Document 對象是 Window對象的一部分,可通過 window.document屬性對其進行訪問。

4. Document 對象屬性和方法

下表是DOM對象的全部屬性和方法列表,在列表下面,詳細地介紹了常見的原生javascript DOM操作。

屬性 / 方法 描述
document.activeElement 返回當前獲取焦點元素
document.addEventListener() 向文檔添加句柄
document.adoptNode(node) 從另外一個文檔返回 adapded節點到當前文檔。
document.anchors 返回對文檔中所有 Anchor 對象的引用。
document.applets 返回對文檔中所有 Applet對象的引用。
document.baseURI 返回文檔的絕對基礎 URI
document.body 返回文檔的body元素
document.close() 關閉用 document.open()方法打開的輸出流,并顯示選定的數據。
document.cookie 設置或返回與當前文檔有關的所有 cookie
document.createAttribute() 創建一個屬性節點
document.createComment() createComment()方法可創建注釋節點。
document.createDocumentFragment() 創建空的 DocumentFragment 對象,并返回此對象。
document.createElement() 創建元素節點。
document.createTextNode() 創建文本節點。
document.doctype 返回與文檔相關的文檔類型聲明 (DTD)。
document.documentElement 返回文檔的根節點
document.documentMode 返回用于通過瀏覽器渲染文檔的模式
document.documentURI 設置或返回文檔的位置
document.domain 返回當前文檔的域名。
document.domConfig 返回normalizeDocument()被調用時所使用的配置
document.embeds 返回文檔中所有嵌入的內容(embed)集合
document.forms 返回對文檔中所有 Form對象引用。
document. getElementsByClassName() 返回文檔中所有指定類名的元素集合。
document.getElementById() 返回對擁有指定 id 的第一個對象的引用。
document.getElementsByName() 返回帶有指定名稱的對象集合。
document.getElementsByTagName() 返回帶有指定標簽名的對象集合。
document.images 返回對文檔中所有Image對象引用。
document.implementation 返回處理該文檔的 DOMImplementation 對象。
document.importNode() 把一個節點從另一個文檔復制到該文檔以便應用。
document.inputEncoding 返回用于文檔的編碼方式(在解析時)。
document.lastModified 返回文檔被最后修改的日期和時間。
document.links 返回對文檔中所有 AreaLink對象引用。
document.normalize() 刪除空文本節點,并連接相鄰節點
document.normalizeDocument() 刪除空文本節點,并連接相鄰節點的
document.open() 打開一個流,以收集來自任何 document.write()document.writeln() 方法的輸出。
document.querySelector() 返回文檔中匹配指定的CSS選擇器的第一元素
document.querySelectorAll() document.querySelectorAll()是 HTML5中引入的新方法,返回文檔中匹配的CSS選擇器的所有元素節點列表
document.readyState 返回文檔狀態 (載入中……)
document.referrer 返回載入當前文檔的文檔的 URL
document.removeEventListener() 移除文檔中的事件句柄(由 addEventListener()方法添加)
document.renameNode() 重命名元素或者屬性節點。
document.scripts 返回頁面中所有腳本的集合。
document.strictErrorChecking 設置或返回是否強制進行錯誤檢查。
document.title 返回當前文檔的標題。
document.URL 返回文檔完整的URL
document.write() 向文檔寫 HTML 表達式 或 JavaScript 代碼。
document.writeln() 等同于write()方法,不同的是在每個表達式之后寫一個換行符。

5. 常見的原生javascript DOM操作

5.1 創建元素

  1. 創建元素節點:document.createElement()
    使用document.createElement()可以創建新元素。這個方法只接受一個參數,即要創建元素的標簽名。這個標簽名在HTML文檔中不區分大小寫,在XHTML中區分大小寫。
var div = document.createElement("div");

此時,新元素尚未被添加到文檔樹中,因此設置各種特性均不會影響瀏覽器的顯示。要添加到文檔樹,可用appendChild()insertBefore()replaceChild()。(稍后講到)

document.body.appendChild(div);

當把元素添加到文檔樹中后,這個元素做的任何修改都會實時地反應到瀏覽器中。

  1. 創建文本節點 :document.createTextNode()
    使用document.createTextNode()來創建文本節點,這個方法接受一個參數:要插入節點的文本。與設置已有文本節點的值一樣,作為參數的文本將按照HTMLXML的格式進行編碼。
document.createTextNode("121212");

可以添加多個文本節點。假如兩個文本節點是相鄰的同胞節點,那么兩個文本節點會連起來,中間不會有空格。

5.2 節點關系

IE9以前不將換行和空格看做文本節點,其他瀏覽器會)

文本關系如下:

<div id="div1">
    <div id="div2">2</div>
    <div id="div3">3</div>
    <div id="div4">4</div>
</div>
  1. 父節點:parentNode
    parentNode是指定節點的父節點。一個元素節點的父節點可能是一個元素(Element )節點,也可能是一個文檔(Document)節點,或者是個文檔碎片(DocumentFragment)節點。
    每一個節點都有一個parentNode屬性。
    對于下面的節點類型: Attr, DocumentDocumentFragment,Entity, Notation,其parentNode屬性返回null。如果當前節點剛剛被建立,還沒有被插入到DOM樹中,則該節點的parentNode屬性也返回null
    var child2 = document.getElementById("div2");
    var parent = child2.parentNode;
  1. 子節點:childNodes
    childNodes 返回包含指定節點的子節點的** 集合**,該集合為即時更新的集合(live collection)。
    即時更新就是對節點元素的任意修改都會立即反映到結果里。
    var child2 = document.getElementById("div2");
    var parent = child2.parentNode;
    var allChilds = parent.childNodes;
    console.log(allChilds.length) // IE下是3,其他瀏覽器是7
    var nodeAdd = document.createElement("div");
    var textAdd = document.createTextNode("這是添加的文本節點");
    nodeAdd.appendChild(textAdd);
    parent.appendChild(nodeAdd);
    console.log(allChilds.length);// IE下是4,其他瀏覽器是8
  1. 兄弟節點:nextSiblingpreviousSibling
    nextSibling返回某節點的下一個兄弟節點,previousSibling返回某節點的上一個兄弟節點,沒有的話返回null
    注意:可能因為元素換行的原因返回的是text節點。
    var child3 = document.getElementById("div3");
    var next = child3.nextSibling;
    var previous = child3.previousSibling;
    console.log(next); // IE下返回div4,其他返回text
    console.log(previous)  // IE下返回div2,其他返回text

第一個或最后一個子節點:firstChildlastChild
firstChild返回node的子節點中的第一個節點的引用,沒有返回null
lastChild返回node的子節點中的最后一個節點的引用,沒有返回null

    var child3 = document.getElementById("div3");
    var parent = child3.parentNode;
    var first = parent.firstChild; // IE是div2,其他是text
    var last = parent.lastChild; // IE是div4,其他是text

5.3 節點元素關系

只算元素,不算文本節點。

以下三個方法用法和節點關系完全一樣,只是這三個方法只看元素節點,不管因為空格、換行造成的文本節點或者手動加上去的文本節點。
children: 返回所有** 元素子節點**(IE5+、ff3.5、opera3、chrome,但在IE8及以下會將注釋節點看成一個元素節點)

以下兩個IE9+才支持
nextElementSibling:返回元素的下一個兄弟元素節點
previousElementSibling: 返回元素的上一個兄弟元素節點

5.4 節點操作

  1. appendChild()
    appendChild()用于向childNodes列表的末尾添加一個節點,并且返回這個新增的節點。
    如果傳入到appendChild()里的節點已經是文檔的一部分了,那結果就是將節點從原來的位置轉移到新位置,任何一個節點不能同時出現在文檔中的多個位置。
    var returnNode = someNode.appendChild(someNode.firstChild);
    // 返回第一個節點
    console.log(returnNode === someNode.firstChild); // false
    console.log(returnNode === someNode.lastChild); // true
  1. insetBefore()
    insetBefore()可以將節點插入到某個特定的位置。這個方法接受兩個參數:要插入的節點和作為參照的節點。
    插入節點后,被插入的節點變成參照節點的前一個同胞節點,同時被方法返回。 如果參照節點是null,則與appendChild()執行相同的操作。
    // 插入后成為最后一個子節點
    var returnNode = someNode.insetBefore(newNode, null);
    console.log(returnNode === someNode.lastChild); // true

    // 插入后成為第一個子節點
    var returnNode = someNode.insetBefore(newNode, someNode.firstChild);
    console.log(returnNode === newNode); // true
    console.log(returnNode === someNode.firstChild); // true

    // 插入到最后一個子節點的前面
    var returnNode = someNode.insetBefore(newNode, someNode.lastChild);
    console.log(returnNode === someNode.childNodes[someNode.childnodes.length - 2]) // true
  1. 替換節點:replaceChild()
    replaceChild()接受兩個參數:要插入的節點和要被替換的節點。被替換的節點將由這個方法返回并從文檔中被移除,同時由要插入的節點占據其位置。
    // 替換第一個子節點
    var returnNode = someNode.replaceChild(newNode, someNode.firstChild);

使用replaceChild()后,被替換的節點的所有關系指針都會被復制到插入的節點上面。

  1. 刪除節點:removeChild()
    該方法移除節點,接受一個參數,即要移除的節點,同時該方法返回被移除的節點。只能是一個節點,不能是一組節點。
    // 移除第一個子節點
    var returnNode = someNode.removeChild(newNode, someNode.firstChild);
  1. 克隆節點:cloneNode(true/false)
    返回調用該方法的節點的一個副本。參數表示是否采用深度克隆,如果為true,則該節點的所有后代節點也都會被克隆,如果為false,則只克隆該節點本身,文本或者換行、空格這些不會復制,因為他們都是一個textNode
    克隆一個元素節點會拷貝它所有的屬性以及屬性值,當然也就包括了屬性上綁定的事件(比如onclick="alert(1)"),但不會拷貝那些使用addEventListener()方法或者node.onclick = fn這種用JavaScript動態綁定的事件。
    注意:為了防止一個文檔中出現兩個ID重復的元素,使用cloneNode()方法克隆的節點在需要時應該指定另外一個與原ID值不同的ID
    var div1 = document.getElementById("div1");
    var cloneHtml = div1.cloneNode(true);
    document.body.appendChild(cloneHtml);

5.5 元素選擇

HTML代碼示例:

<div id="div1">
    <p id="div2" class="one" name="nameone">2</p>
    <div id="div3">3</div>
    <div id="div4" name="div2">4</div>
</div>
  • querySelector
    返回節點子樹內與之相匹配的第一個Element節點。如果沒有匹配的節點,則返回null
  • querySelectorAll
    返回一個包含節點子樹內所有與之相匹配的Element節點列表,如果沒有相匹配的,則返回一個空節點列表。
    注意:querySelector()querySelectorAll()返回的節點列表不是動態實時的(非live Collection)。這和其他DOM查詢方法返回動態實時節點列表不一樣。
    選擇器方法接受一個或多個用逗號分隔的選擇器來確定需要被返回的元素。例如,要選擇文檔中所有CSS的類(class)是warning或者note的段落(p)元素,可以這樣寫:
var special = document.querySelectorAll( "p.warning, p.note" );

也可以通過ID來查詢,例如:

var el = document.querySelector( "#main, #basic, #exclamation" );

執行上面的代碼后,el就包含了文檔中元素的ID是mainbasicexclamation的所有元素中的第一個元素。querySelector() and querySelectorAll()里可以使用任何CSS選擇器,他們都不是live Collection

var notLive = document.querySelectorAll("p");
console.log(notLive);
document.getElementById("div1").removeChild(document.getElementById("div2"));
console.log(notLive);
// 上面兩個輸出都是輸出 `p#div2.one`的引用,沒有因為刪除了`p`標簽而使`notLive`的結果發生變化。
  • document.getElementById()方法
返回指定 ID 的元素:
document.getElementById("demo");
  • document.getElementsByTagName()方法
返回帶有指定標簽名的對象的集合:
document.getElementsByTagName("P");
  • document.getElementsByName()方法,常用于表單(數組)
var x=document.getElementsByName("x");//x為元素name屬性值
alert(x.length);
  • getElementsByClassName()方法
    當在 document對象上調用此方法時,會檢索整個文檔,包括根元素。(IE9以下不支持)要匹配多個class,則className用空格分開。
getElementsByClassName("class1 class2");

5.6 屬性操作

  • setAttribute()
    添加一個新屬性(attribute)到元素上,或改變元素上已經存在的屬性的值。
    如果指定的屬性已經存在,則其值變為傳遞的值。如果不存在,則創建指定的屬性。也可指定為null。如果設置為null,最好使用removeAttribute()
var div2 = document.getElementById("div2"); 
div2.setAttribute("class", "new_class"); 
div2.setAttribute("id", "new_id");
  • removeAttribute()
    該方法用于移除元素的屬性。
    var div2 = document.getElementById("div2");
    div2.removeAttribute("class");
  • getAttribute()
    該方法返回元素上指定屬性(attribute)的值。如果指定的屬性不存在,則返回null""(空字符串)。
    var div2 = document.getElementById("div2");
    var attr = div2.getAttribute("class");
    console.log(attr);
  • hasAttribute()
    hasAttribute()返回一個布爾值,指示該元素是否包含有指定的屬性(attribute)。

參考資料:
常見的原生javascript DOM操作
廖雪峰的官方網站

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 本篇是基于《JavaScript高級程序設計(第3版)》DOM相關章節做的整理與歸納,概述了DOM的常見節點類型及...
    查查查查查查克閱讀 2,576評論 2 7
  • 工廠模式類似于現實生活中的工廠可以產生大量相似的商品,去做同樣的事情,實現同樣的效果;這時候需要使用工廠模式。簡單...
    舟漁行舟閱讀 7,842評論 2 17
  • 轉載請聲明出處 博客原文 隨手翻閱以前的學習筆記,順便整理一下放在這里,方便自己復習,也希望你有也有幫助吧 第一課...
    前端進階之旅閱讀 12,756評論 13 94
  • 話說,說起閨蜜,你們第一個想到誰,經常會有一種誤區就是說:閨蜜嘛不就是整天膩歪在一起,一起洗洗澡、按按摩、燙燙頭發...
    A大棋小姐閱讀 946評論 0 2
  • 當黎明的第一縷陽光 悠然撒進窗欞 像羽毛一樣 那般無聲,輕柔的 撫摸著 干涸的大地 在睡夢中呢喃 呢喃著 故國的青...
    姀蕭閱讀 223評論 1 10