javascript基礎DOM操做

DOM 中的三個字母,D(文檔)能夠理解爲整個 Web 加載的網頁文檔;O(對象)能夠理解爲相似 window 對象之類的東西,能夠調用屬性和方法,這裏咱們說的是 document對象;M(模型)能夠理解爲網頁文檔的樹型結構。javascript

DOM 有三個等級,分別是 DOM一、DOM二、DOM3,而且 DOM1 在 1998 年 10 月成爲W3C 標準。DOM1 所支持的瀏覽器包括 IE6+、Firefox、Safari、Chrome 和 Opera1.7+。html

1.節點java

加載 HTML 頁面時,Web 瀏覽器生成一個樹型結構,用來表示頁面內部結構。DOM 將這種樹型結構理解爲由節點組成。node

節點樹數組

從上圖的樹型結構,咱們理解幾個概念,html 標籤沒有父輩,沒有兄弟,因此 html 標籤爲根標籤。head 標籤是 html 子標籤,meta 和 title 標籤之間是兄弟關係。若是把每一個標籤看成一個節點的話,那麼這些節點組合成了一棵節點樹。瀏覽器

PS:後面咱們常常把標籤稱做爲元素,是一個意思。app

2.節點種類:元素節點、文本節點、屬性節點。函數

<div title="屬性節點">測試 Div</div>

二.查找元素測試

W3C 提供了比較方便簡單的定位節點的方法和屬性,以便咱們快速的對節點進行操做。分別爲:getElementById()、getElementsByTagName()、getElementsByName()、getAttribute()、setAttribute()和 removeAttribute()。spa

元素節點方法

1.getElementById()方法

getElementById()方法,接受一個參數:獲取元素的 ID。若是找到相應的元素則返回該元素的 HTMLDivElement 對象,若是不存在,則返回 null。

document. getElementById('box');//獲取 id 爲 box 的元素節點

PS:上面的例子,默認狀況返回 null,這無關是否存在 id="box"的標籤,而是執行順序問題。解決方法,1.把 script 調用標籤移到 html 末尾便可;2.使用 onload 事件來處理 JS,等待 html 加載完畢再加載 onload 事件裏的 JS。

window. onload function ({//預加載 html 後執行
   document.getElementById('box');
};

PS:id 表示一個元素節點的惟一性,不能同時給兩個或以上的元素節點建立同一個命名的 id。某些低版本的瀏覽器會沒法識別 getElementById()方法,好比 IE5.0-,這時須要作一些判斷,能夠結合上章的瀏覽器檢測來操做。

if (document.getElementById{//判斷是否支持 getElementById
   alert('當前瀏覽器支持 getElementById');
}

當咱們經過 getElementById()獲取到特定元素節點時,這個節點對象就被咱們獲取到了,而經過這個節點對象,咱們能夠訪問它的一系列屬性。

元素節點屬性

document. getElementById('box').tagName;//DIV
document.getElementById('box').innerHTML;//測試 Div

HTML 屬性的屬性

document. getElementById('box').id;//獲取 id
document.getElementById('box').id 'person';//設置 id
document. getElementById('box').title;//獲取 title
document.getElementById('box').title '標題';//設置 title
document. getElementById('box').style;//獲取 CSSStyleDeclaration 對象
document.getElementById('box').style.color;//獲取 style 對象中 color 的值
document.getElementById('box').style.color 'red'//設置 style 對象中 color 的值
document. getElementById('box').className;//獲取 class
document.getElementById('box').className 'box'//設置 class
alert(document.getElementById('box').bbb);//獲取自定義屬性的值,非 IE 不支持

2.getElementsByTagName()方法

getElementsByTagName()方法將返回一個對象數組 HTMLCollection(NodeList),這個數組保存着全部相同元素名的節點列表。

document. getElementsByTagName('*');//獲取全部元素

PS:IE 瀏覽器在使用通配符的時候,會把文檔最開始的 html 的規範聲明看成第一個元素節點。

document. getElementsByTagName('li');//獲取全部 li 元素,返回數組
document.getElementsByTagName('li')[0];//獲取第一個 li 元素,HTMLLIElement
document.getElementsByTagName('li').item(0);//獲取第一個 li 元素,HTMLLIElement
document.getElementsByTagName('li').length;//獲取全部 li 元素的數目

PS:不論是 getElementById 仍是 getElementsByTagName,在傳遞參數的時候,並非全部瀏覽器都必須區分大小寫,爲了防止沒必要要的錯誤和麻煩,咱們必須堅持養成區分大小寫的習慣。

3.getElementsByName()方法

getElementsByName()方法能夠獲取相同名稱(name)的元素,返回一個對象數組HTMLCollection(NodeList)。

document. getElementsByName('add')//獲取 input 元素
document.getElementsByName('add')[0].value //獲取 input 元素的 value 值
document.getElementsByName('add')[0].checked //獲取 input 元素的 checked 值

PS:對於並非 HTML 合法的屬性,那麼在 JS 獲取的兼容性上也會存在差別,IE 瀏覽器支持自己合法的 name 屬性,而不合法的就會出現不兼容的問題。

4.getAttribute()方法

getAttribute()方法將獲取元素中某個屬性的值。它和直接使用.屬性獲取屬性值的方法有必定區別。

document. getElementById('box').getAttribute('id');//獲取元素的 id 值
document.getElementById('box').id;//獲取元素的 id 值
document.getElementById('box').getAttribute('mydiv');//獲取元素的自定義屬性值
document.getElementById('box').mydiv//獲取元素的自定義屬性值, IE 不支持非
document.getElementById('box').getAttribute('class');//獲取元素的 class 值,IE 不支持
document.getElementById('box').getAttribute('className');//非 IE 不支持

PS:HTML 通用屬性 style 和 onclick,IE7 更低的版本 style 返回一個對象,onclick 返回一個函數式。雖然 IE8 已經修復這個 bug,但爲了更好的兼容,開發人員只有儘量避免使用 getAttribute()訪問 HTML 屬性了,或者碰到特殊的屬性獲取作特殊的兼容處理。

5.setAttribute()方法

setAttribute()方法將設置元素中某個屬性和值。它須要接受兩個參數:屬性名和值。若是屬性自己已存在,那麼就會被覆蓋。

document. getElementById('box').setAttribute('align','center');//設置屬性和值
document.getElementById('box').setAttribute('bbb','ccc');//設置自定義的屬性和值

PS:在 IE7 及更低的版本中,使用 setAttribute()方法設置 class 和 style 屬性是沒有效果的,雖然 IE8 解決了這個 bug,但仍是不建議使用。

6.removeAttribute()方法

removeAttribute ()能夠移除 HTML 屬性。
document.getElementById('box').removeAttribute('style');//移除屬性

PS:IE6 及更低版本不支持 removeAttribute()方法。

三.DOM 節點

1.node 節點屬性

節點能夠分爲元素節點、屬性節點和文本節點,而這些節點又有三個很是有用的屬性,分別爲:nodeName、nodeType 和 nodeValue。

信息節點屬性

document. getElementById('box').nodeType;//1,元素節點

2.層次節點屬性

節點的層次結構能夠劃分爲:父節點與子節點、兄弟節點這兩種。當咱們獲取其中一個元素節點的時候,就可使用層次節點屬性來獲取它相關層次的節點。

層次節點屬性

1.childNodes 屬性

childeNodes 屬性能夠獲取某一個元素節點的全部子節點,這些子節點包含元素子節點和文本子節點。

var box = document.getElementById('box');//獲取一個元素節點
alert(box.childNodes.length);//獲取這個元素節點的全部子節點
alert(box.childNodes[0]);//獲取第一個子節點對象

PS:使用 childNodes[n]返回子節點對象的時候,有可能返回的是元素子節點,好比HTMLElement;也有可能返回的是文本子節點,好比 Text。元素子節點可使用 nodeName或者 tagName 獲取標籤名稱,而文本子節點可使用 nodeValue 獲取。

for (var i 0; i < box.childNodes.length; i ++{
   //判斷是元素節點,輸出元素標籤名
   if (box.childNodes[i].nodeType === 1{
      alert('元素節點:' + box.childNodes[i].nodeName);
   //判斷是文本節點,輸出文本內容
   else if (box.childNodes[i].nodeType === 3{
      alert('文本節點:' + box.childNodes[i].nodeValue);
   }
}

PS:在獲取到文本節點的時候,是沒法使用 innerHTML 這個屬性輸出文本內容的。這個非標準的屬性必須在獲取元素節點的時候,才能輸出裏面包含的文本。

alert(box.innerHTML);//innerHTML 和 nodeValue 第一個區別

PS:innerHTML 和 nodeValue 第一個區別,就是取值的。那麼第二個區別就是賦值的時候,nodeValue 會把包含在文本里的 HTML 轉義成特殊字符,從而達到造成單純文本的效果。

box. childNodes[0].nodeValue '<strong>abc</strong>';//結果爲:<strong>abc</strong>
abcbox.innerHTML '<strong>abc</strong>';//結果爲:abc

2.firstChild 和 lastChild 屬性

firstChild 用於獲取當前元素節點的第一個子節點,至關於 childNodes[0];lastChild 用於獲取當前元素節點的最後一個子節點,至關於 childNodes[box.childNodes.length - 1]。

alert(box.firstChild.nodeValue);//獲取第一個子節點的文本內容
alert(box.lastChild.nodeValue);//獲取最後一個子節點的文本內容

3.ownerDocument 屬性

ownerDocument 屬性返回該節點的文檔對象根節點,返回的對象至關於 document。

alert(box.ownerDocument === document);//true,根節點

4.parentNode、previousSibling、nextSibling 屬性

parentNode 屬性返回該節點的父節點,previousSibling 屬性返回該節點的前一個同級節點,nextSibling 屬性返回該節點的後一個同級節點。

alert(box.parentNode.nodeName);//獲取父節點的標籤名
alert(box.lastChild.previousSibling);//獲取前一個同級節點
alert(box.firstChild.nextSibling);//獲取後一個同級節點

5.attributes 屬性

attributes 屬性返回該節點的屬性節點集合。

document. getElementById('box').attributes//NamedNodeMap
document.getElementById('box').attributes.length;//返回屬性節點個數
document.getElementById('box').attributes[0]//Attr,返回最後一個屬性節點
document.getElementById('box').attributes[0].nodeType//2,節點類型
document.getElementById('box').attributes[0].nodeValue//屬性值
document.getElementById('box').attributes['id']//Attr,返回屬性爲 id 的節點
document.getElementById('box').attributes.getNamedItem('id')//Attr

6.忽略空白文本節點

var body = document.getElementsByTagName('body')[0];//獲取 body 元素節點
alert(body.childNodes.length);//獲得子節點個數,IE3 個,非 IE7 個

PS:在非 IE 中,標準的 DOM 具備識別空白文本節點的功能,因此在火狐瀏覽器是 7個,而 IE 自動忽略了,若是要保持一致的子元素節點,須要手工忽略掉它。

function filterSpaceNode(nodes{
   var ret [];//新數組
   for (var i 0; i < nodes.length; i ++{
      //若是識別到空白文本節點,就不添加數組
      if (nodes[i].nodeType == &amp;&amp/^\s+$/.test(nodes[i].nodeValue)continue;
      //把每次的元素節點,添加到數組裏
      ret.push(nodes[i]);
   }
   return ret;
}

PS:上面的方法,採用的忽略空白文件節點的方法,把獲得元素節點累加到數組裏返回。那麼還有一種作法是,直接刪除空位文件節點便可。

function filterSpaceNode(nodes{
   for (var i 0; i < nodes.length; i ++{
      if (nodes[i].nodeType == &amp;&amp/^\s+$/.test(nodes[i].nodeValue){
         //獲得空白節點以後,移到父節點上,刪除子節點
         nodes[i].parentNode.removeChild(nodes[i]);
      }
   }
   return nodes;
}

PS:若是 firstChild、lastChild、previousSibling 和 nextSibling 在獲取節點的過程當中遇到空白節點,咱們該怎麼處理掉呢?

function removeWhiteNode(nodes{
for (var i 0; i < nodes.childNodes.length; i ++{
   if (nodes.childNodes[i].nodeType === &amp;&amp;
      /^\s+$/.test(nodes.childNodes[i].nodeValue){
      nodes.childNodes[i].parentNode.removeChild(nodes.childNodes[i]);
   }
}
return nodes;
}

四.節點操做

DOM 不僅僅能夠查找節點,也能夠建立節點、複製節點、插入節點、刪除節點和替換節點。

節點操做方法

1.write()方法
write()方法能夠把任意字符串插入到文檔中去。

document. write('<p>這是一個段落!</p>')';//輸出任意字符串

2.createElement()方法
createElement()方法能夠建立一個元素節點。

document. createElement('p');//建立一個元素節點

3.appendChild()方法
appendChild()方法講一個新節點添加到某個節點的子節點列表的末尾上。

var box = document.getElementById('box');//獲取某一個元素節點
var p = document.createElement('p');//建立一個新元素節點<p>
box.appendChild(p);//把新元素節點<p>添加子節點末尾

4.createTextNode()方法
createTextNode()方法建立一個文本節點。

var text = document.createTextNode('段落');//建立一個文本節點
p.appendChild(text);//將文本節點添加到子節點末尾

5.insertBefore()方法

insertBefore()方法能夠把節點建立到指定節點的前面。

box. parentNode.insertBefore(p, box);//把<div>以前建立一個節點

PS:insertBefore()方法能夠給當前元素的前面建立一個節點,但卻沒有提供給當前元素的後面建立一個節點。那麼,咱們能夠用已有的知識建立一個 insertAfter()函數。

function insertAfter(newElement, targetElement{
   //獲得父節點
   var parent = targetElement.parentNode;
   //若是最後一個子節點是當前元素,那麼直接添加便可
   if (parent.lastChild === targetElement{
      parent.appendChild(newElement);
   else {
      //不然,在當前節點的下一個節點以前添加
      parent.insertBefore(newElement, targetElement.nextSibling);
   }
}

PS:createElement 在建立通常元素節點的時候,瀏覽器的兼容性都還比較好。但在幾個特殊標籤上,好比 iframe、input 中的 radio 和 checkbox、button 元素中,可能會在 IE6,7如下的瀏覽器存在一些不兼容。

var input null;
if (BrowserDetect.browser == 'Internet Explorer' &amp;&amp; BrowserDetect.version <= 7{
   //判斷 IE6,7,使用字符串的方式
   input = document.createElement("<input type=\"radio\" name=\"sex\">");
else {
   //標準瀏覽器,使用標準方式
   input = document.createElement('input');
   input.setAttribute('type''radio');
   input.setAttribute('name''sex');
}
document.getElementsByTagName('body')[0].appendChild(input);

6.repalceChild()方法
replaceChild()方法能夠把節點替換成指定的節點。

box. parentNode.replaceChild(p,box);//把<div>換成了<p>

7.cloneNode()方法

cloneNode()方法能夠把子節點複製出來。

var box = document.getElementById('box');
var clone = box.firstChild.cloneNode(true);//獲取第一個子節點,true 表示複製內容
box.appendChild(clone);//添加到子節點列表末尾

8.removeChild()方法

removeChild()方法能夠把

box. parentNode.removeChild(box);//刪除指定節點
 
綜合應用
Q:節點增、刪、替換、插入
A:一、建立節點
var oP = document.createElement("p");
var oT = document.createTextNode("寫入的文本");
oP.appendChild(oT);
document.body.appendChild(oP);

      二、刪除節點

function RemoveNode(){
     var oNewP = document.getElementsByTagName("p")[0];
     oNewP.parentNode.removeChild(oNewP);
}

     三、替換

function ReplaceNode(){
     var oNewP = document.getElementsByTagName("p")[0];
     var oNewDiv = document.createElement("div");
     oNewDiv.innerHTML = "<p>文字</p>";
     oNewP.parentNode.replaceChild(oNewDiv,oNewP);
}

 

     四、插入

 

function InsertNode(){
    var oNewP = document.getElementsByTagName("p")[0];
    var oNewDiv = document.crenteElement("div");
    oNewDiv.innerHTML = "<br/>文字";
   oNewP.parentNode.insertBefoe(oNewDiv,oNewP);
}
相關文章
相關標籤/搜索