因為 DOM 的存在,這使我們可以通過 JavaScript 來獲取、創建、修改、或刪除節點。 NOTE:下面提供的例子中的 element 均為元素節點。 獲取節點父子關系element.parentNodeelement.firstChild/element.lastChildelement.childNodes/element.children兄弟關系element.previousSibling/element.nextSiblingelement.previousElementSibling/element.nextElementSibling通過節點直接的關系獲取節點會導致代碼維護性大大降低(節點之間的關系變化會直接影響到獲取節點),而通過接口則可以有效的解決此問題。通過節點直接的關系獲取節點會導致代碼維護性大大降低(節點之間的關系變化會直接影響到獲取節點),而通過接口則可以有效的解決此問題。 !DOCTYPE html html lang="en" head meta charset="UTF-8" title ELEMENT_NODE & TEXT_NODE /title /head body ul id="ul" li First /li li Second /li li Third /li li Fourth /li /ul p Hello /p script type="text/javascript" var ulNode = document.getElementsByTagName("ul")[0]; console.log(ulNode.parentNode); // body /body console.log(ulNode.previousElementSibling); //null console.log(ulNode.nextElementSibling); // p Hello /p console.log(ulNode.firstElementChild); // li First /li console.log(ulNode.lastElementChild); // li Fourth /li /script /body /html NTOE:細心的人會發現,在節點遍歷的例子中,body、ul、li、p節點之間是沒有空格的,因為如果有空格,那么空格就會被當做一個TEXT節點,從而用ulNode.previousSibling獲取到得就是一個空的文本節點,而不是 li First /li 節點了。即節點遍歷的幾個屬性會得到所有的節點類型,而元素遍歷只會得到相對應的元素節點。一般情況下,用得比較多得還是元素節點的遍歷屬性。 實現瀏覽器兼容版的element.children 有一些低版本的瀏覽器并不支持 element.children 方法,但我們可以用下面的方式來實現兼容。 html lang head meta charest="utf-8" title Compatible Children Method /title /head body id="body" div id="item" div 123 /div p ppp /p h1 h1 /h1 /div script type="text/javascript" function getElementChildren(e){ if(e.children){ return e.children; }else{ /* compatible other browse */ var i, len, children = []; var child = element.firstChild; if(child != element.lastChild){ while(child != null){ if(child.nodeType == 1){ children.push(child); child = child.nextSibling; }else{ children.push(child); return children; /* Test method getElementChildren(e) */ var item = document.getElementById("item"); var children = getElementChildren(item); for(var i =0; i children.length; i++){ alert(children[i]); /script /body /html NOTE:此兼容方法為初稿,還未進行兼容性測試。 接口獲取元素節點getElementByIdgetElementsByTagNamegetElementsByClassNamequerySelectorquerySelectorAllgetElementById獲取文檔中指定 id 的節點對象。 var element = document.getElementById('id');getElementsByTagName動態的獲取具有指定標簽元素節點的集合(其返回值會被 DOM 的變化所影響,其值會發生變化)。此接口可直接通過元素而獲取,不必直接作用于 document 之上。 // 示例var collection = element.getElementsByTagName('tagName');// 獲取指定元素的所有節點var allNodes = document.getElementsByTagName('*');// 獲取所有 p 元素的節點var elements = document.getElementsByTagName('p');// 取出第一個 p 元素var p = elements[0]; getElementsByClassName 獲取指定元素中具有指定 class 的所有節點。多個 class 可的選擇可使用空格分隔,與順序無關。 var elements = element.getElementsByClassName('className'); NOTE:IE9 及一下版本不支持 getElementsByClassName 兼容方法 function getElementsByClassName(root, className) { // 特性偵測 if (root.getElementsByClassName) { // 優先使用 W3C 規范接口 return root.getElementsByClassName(className); } else { // 獲取所有后代節點 var elements = root.getElementsByTagName('*'); var result = []; var element = null; var classNameStr = null; var flag = null; className = className.split(' '); // 選擇包含 class 的元素 for (var i = 0, element; element = elements[i]; i++) { classNameStr = ' ' + element.getAttribute('class') + ' '; flag = true; for (var j = 0, name; name = className[j]; j++) { if (classNameStr.indexOf(' ' + name + ' ') === -1) { flag = false; break; if (flag) { result.push(element); return result;querySelector / querySelectorAll獲取一個 list (其返回結果不會被之后 DOM 的修改所影響,獲取后不會再變化)符合傳入的 CSS 選擇器的第一個元素或全部元素。 var listElementNode = element.querySelector('selector');var listElementsNodes = element.querySelectorAll('selector');var sampleSingleNode = element.querySelector('#className');var sampleAllNodes = element.querySelectorAll('#className');NOTE: IE9 一下不支持 querySelector 與 querySelectorAll 創建節點創建節點 - 設置屬性 - 插入節點 var element = document.createElement('tagName');修改節點textContent 獲取或設置節點以及其后代節點的文本內容(對于節點中的所有文本內容)。 element.textContent; // 獲取element.textContent = 'New Content';NOTE:不支持 IE 9 及其一下版本。 innerText (不符合 W3C 規范) 獲取或設置節點以及節點后代的文本內容。其作用于 textContent 幾乎一致。 element.innerText;NOTE:不符合 W3C 規范,不支持 FireFox 瀏覽器。 FireFox 兼容方案 if (!('innerText' in document.body)) { HTMLElement.prototype.__defineGetter__('innerText', function(){ return this.textContent; HTMLElement.prototype.__defineSetter__('innerText', function(s) { return this.textContent = s;插入節點appendChild在指定的元素內追加一個元素節點。 var aChild = element.appendChild(aChild);insertBefore在指定元素的指定節點前插入指定的元素。 var aChild = element.insertBefore(aChild, referenceChild);刪除節點刪除指定的節點的子元素節點。 var child = element.removeChild(child);innerHTML獲取或設置指定節點之中所有的 HTML 內容。替換之前內部所有的內容并創建全新的一批節點(去除之前添加的事件和樣式)。innerHTML 不檢查內容,直接運行并替換原先的內容。 NOTE:只建議在創建全新的節點時使用。不可在用戶可控的情況下使用。 var elementsHTML = element.innerHTML;存在的問題+ 低版本 IE 存在內存泄露 安全問題(用戶可以在名稱中運行腳本代碼)PS: appendChild() , insertBefore()插入節點需注意的問題 使用appendChild()和insertBefore()插入節點都會返回給插入的節點,//由于這兩種方法操作的都是某個節點的子節點,所以必須現取得父節點,代碼中 someNode 表示父節點 //使用appendChild()方法插入節點 var returnedNode = someNode.appendChild(newNode); alert(returnedNode == newNode) //true //使用insertBefore()方法插入節點 var returnedNode = someNode.appendChild(newNode); alert(returnedNode == newNode) //true 值得注意的是,如果這兩種方法插入的節點原本已經存在與文檔樹中,那么該節點將會被移動到新的位置,而不是被復制。 div id="test" div adscasdjk /div div id="a" adscasdjk /div /div script type="text/javascript" var t = document.getElementById("test"); var a = document.getElementById('a'); //var tt = a.cloneNode(true); t.appendChild(a); /script 在這段代碼中,頁面輸出的結果和沒有Javascript時是一樣的,元素并沒有被復制,由于元素本來就在最后一個位置,所以就和沒有操作一樣。如果把id為test的元素的兩個子元素點換位置,就可以在firbug中看到這兩個div已經被調換了位置。 如果我們希望把id為a的元素復制一個,然后添加到文檔中,那么必須使被復制的元素現脫離文檔流。這樣被添加復制的節點被添加到文檔中之后就不會影響到文檔流中原本的節點。即我們可以把復制的元素放到文檔的任何地方,而不影響被復制的元素。下面使用了cloneNode()方法,實現節點的深度復制,使用這種方法復制的節點會脫離文檔流。當然,我不建議使用這種方法復制具有id屬性的元素。因為在文檔中id值是唯一的。 div id="test" div adscasdjk /div div id="a" adscasdjk /div /div script type="text/javascript" var t = document.getElementById("test"); var a = document.getElementById('a'); var tt = a.cloneNode(true); t.appendChild(tt); /script 相似的操作方法還有 removeNode(node)刪除一個節點,并返回該節;replaceNode(newNode,node)替換node節點,并返回該節點。這兩種方法相對來說更容易使用一些。更多編程語言