DOM文檔樹和節點操做

1 DOM文檔樹

1.1 DOM的定義(document object modle)

DOM就是文檔對象模型javascript

/* 查看這段HTML代碼中p的DOM模型 */
<html>
    <head>
        <meta charset="utf-8">
        <link href="style.css">
    </head>
    <body>
        ---
        <p class="mooc">
            hello,<span>mooc</span>
            <img src='user.jpg'>
        </p>
        ---
        <div id="div">
            <h3><a href="">喬丹</a></h3>
            <p>NBA<em>最偉大</em>的球員</p>
        </div>
        ---
        <div>前端微專業</div>
    </body>
</html>

//在調試窗口中查看 childNodes children 對比差別
var p = document.getElementsByTagName('p');
var div = document.getElementById('div');

console.log(p);
console.log(div);

1.2 DOM API

interface Document:Node{
    readonly attribute  DOMImplementation implementation;
    readonly attribute  Element DocumentElement;
    Element             createElement(in DOMString tagName)
                        raises(DOMException);
    DocumentFragment    createDocumentFragment();
    Text                createTextNode(in DOMString data);
    Comment             createComment(in DOMstring date);
    NodeList            getElementsByTagName(in DOMString tagname);
    Element             getElementById(in DOMString elementID);

1.3 瀏覽器中的DOM

在瀏覽器中DOM和JS的關係:{JS[,DOM]};css

1.4 DOM的內容

DOM的內容包括:DOM Core,DOM HTML,DOM Style,DOM Eventhtml

1.5 DOM樹

<html>
    <head>
        <meta charset="utf-8">
        <link href="style.css">
    </head>
    <body>
        <p class="mooc">
            hello,<span>mooc</span>
            <img src='user.jpg'>
        </p>
        <div>前端微專業</div>
    </body>
</html>

上面這段代碼的DOM樹以下所示:前端

DOMtree

1.6 節點遍歷

可用node.parentNode,node.firstChild,node.lastChild,node.previousSibling,node.nextSibiling來遍歷DOM節點;java

注:節點(node)的操做,必須是node節點,不能是nodes-collection。node

DOMnodetree

1.7 節點類型

DOM節點分爲:element_node,text_node,comment_node,document_type_node;

在【4.1.6】和【4.1.7】的樹狀圖中,圓型節點表示element_node,方形節點表示text_node.api

1.8 元素遍歷

以下一段HTML代碼:數組

<p>
    hello,<em>jerry!</em>
    歡迎來<a href="#">China</a>。
</p>

上面HTML代碼的DOM樹以下所示:瀏覽器

DOMtree

//獲取'hello,'和'。'
p.firstChild
p.lastChild

p.firstElementChild//<em>jerry!</em>
p.lastElementChild//<a href="#">Chia</a>

em.nextElementSibling //<a href="#">China</a>
em.previousElementSibling //null  而不是undefined!!!

2 節點操做

2.1 獲取節點

  • 經過元素關係獲取節點
    • 父子關係
      • parentNode
      • firstChild/firstElementChild,lastChild/lastElementChild
      • childnodes/children
    • 兄弟關係
      • previousSibling/nextSibling
      • previousElementSibling/nextElementSibling

可是,經過元素關係獲取節點,可維護性不好!!!app

  • 經過接口獲取關係
    • getElementById
    • getElementsByTagName
    • getElementsByClassName
    • querySelector/All

2.1-A getElementById

/* getElementById */
/* element = document.getElementById(id) */
---
<body>
    <p id="hello" class="mooc">
        hello,<span>mooc</span><img src="user.jpg">
    </p>
</body>
---
//獲取id爲hello的p
document.getElementById("hello")//在console面板中應該獲得「p#hello.mooc」的DOM對象

2.1-B getElementsByTagName

/* getElementsByTagName */
/* collection = element.getElementsByTagName(tagName) */
---
<div id="users">
    <h2>8882人在學習該課程</h2>
    <ul>
        <li class="user">Satoshi</li>
        <li class="user">春來草青</li>
        <li class="user last">Kash</li>
    </ul>
</div>
//切記,這裏不能用p來代替div!!!
---
//先獲取div#users對象,在用div#user對象來獲取li對象
var users = document.getElementById("users");
//獲取li
users.getElementsByTagName("li");//[li.user,li.user,li.user.last]
users.getElementsByTagName("li")[2];//li.user.last:<li class="user last">Kash</li>
//獲取所有的tag
users.getElementsByTagName("*");//[h2,ul,li.user,li.user,li.user.last]
/* 注:getElementsByTagName獲得的collection是動態的 */

2.1-C getElementsByClassName

/* getElementsByClassName */
/* collection = element.getElementsyClassName(className) */
---
<div id="users">
    <h2>the story of Qin dynasty</h2>
    <ul>
        <li class="user">Qinshi moon</li>
        <li class="user">tianxingjiuge</li>
        <li class="user last">daqindiguo</li>
    </ul>
</div>
---
//先獲取div#users對象,再用div#users對象來獲取li對象
var users = document.getElementById("users");
//獲取li
users.getElementsByClassName("user");//[li.user,li.user,li.user.last]
users.getElementsByClassName("user")[2];//[li.user.last]
users.getElementsByClassName("user last"); !== user.getElementsByClassName("last user");//[li.user.last]
//上面兩個雖然形式上看起來同樣,可是前一個是一個數組的項,後一個是一個數組。

/* 兼容IE6,7,8的getElementsByClassName */
function getElementsByClassName(root,className){
    //特性偵測
    if(root.getElementsByClassName){
        //優先使用W3C規範
        return root.getElementsByClassName(className);
    }else{
        //獲取全部的後代元素
        var elements = root.getElementsByTagName("*");
        var result = [];
        for(var i=0,element;element=elements[i];i++){
            //選擇包含有類名的元素並push到新的Array
            if(hasClassName(element,className)){
                result.push(element);
            }
        }
        return result;
    }
}
/* getElementsByClassName獲得的collection是動態的 */

2.1-D querySelector/All

/* querySelector/All */
/* list = element.querySelector/All(selector) */
---
<div id="users">
    <h2>a faiary tale</h2>
    <ul>
        <li class="user">for child</li>
        <li class="user">for adult</li>
        <li class="user last">for all</li>
    </ul>
</div>
---
//用querySelector獲取div#users
var users = document.querySelector("#users");//div#users
//用querySelectorAll獲取.user
users.querySelectorAll(".user");//[li.user,li.user,li.user.last]
document.querySelectorAll("#users .user");//[li.user,li.user,li.user.last]
/* querySelector/All獲得的list是非動態的。*/

2.2 建立節點

/* createElement(tagName) */
/* element = document.createElement(tagName) */
document.creatElement("div");//<div></div>
document.creatElement("a");//<a></a>
var sc = document.createElement("script");//<script></script>

2.3 修改節點

2.3-A textContent

/* element.textContent */
---
<div class="users">
    <h2>there are three boys</h2>
    <ul>
        <li class="user">one</li>
        <li class="user">two</li>
        <li class="user last">tree</li>
    </ul>
</div>
---
//首先獲取或者建立節點
var users = document.getElementById("users");
//讀取或修改node的內容
users.textContent;//"there are three boys one two three"

users.last.textContent;//"tree"//is this right?錯啦!!!
users.lastElementChild.lastElementChild.textContent;//"tree"

users.last.textcontent = "three";//is this right?錯了!!!
users.lastElementChild.lastElementChild.textContent="three";//"three"
/* ie9不支持textContent */

2.3-B innerText

/* element.innerText */
//兼容firefox
if(!('innerText'in document.body)){
    HTMLElement.prototype._defineGetter_("innerText",function(){
        return this.textContent;
    });
    HTMLElement.prototype._defineSetter_("innerText",function(s){
        return this.TextContent=s;
    });
}

2.4 插入節點

2.4-A appendChild

/* appendChild */
/* var achild = element.appendChild(achild); */
---
<div id="users">
    <h2>I can do what I want to do</h2>
    <ul>
        <li class="user">
            <img src="4.jpg">
            <a href="/user/4">lifeng</a>
        </li>
    </ul>
</div>
---
//完場上述HTML段落
var users = document.getElementById("users");//得到div#user節點
var h2 = document.createElement("h2");//建立h2
var ul = document.createElement("ul");//建立ul
users.appendChild(h2);//添加h2到div#users
users.appendChild(ul);//添加ul到div#users
var li = document.createElement("li");//建立li
li.className = "user";//li的className
ul.appendChild(li);//添加li到ul
var img = document.createElement("img");//建立img
img.src = "4.jpg";//設置img的src
li.appendChild(img);//添加img到li
var a = document.createElement("a");//建立a
a.href = "/user/4";//設置a的href
a.innerText = "lifeng";//設置a的innerText
li.appendChild(a);//添加a到li

2.4-B insertBefore

/* insertBefore */
element.insertBefore(achild,referenceChild);
---
<div id="users">
    <h2>you need to work harder</h2>
    <ul></ul>
</div>
---
//完成上述需求
var users = document.getElementById("users");//獲取div#users
var h2 = document.createElement("h2");//建立h2
var ul = document.createElement("ul");//建立ul
users.appendChild(ul);//插入ul
users.insertBefore(h2,ul);//在ul前面插h2

2.5 刪除節點

/* removeChild */
/* element.removeChild(child) */
var user2 = users.getElementByClassName("user2");//獲取到.user2
user2.parentNode.removeChild(user2);//經過user2.parentNode來刪除user2

2.6 innerHTML

/* element.innerHTML */
---
<ul id="users">
    <li class="user">
        <img src="4.jpg">
        <a href="/user/4">yahoo</a>
    </li>
</ul>
---
//用innerHTML方法在ul#users下添加元素
var users = document.getElementById("users");//獲取ul#users
var li = document.createElement("li");//建立li
li.className="user";//設置li的className
users.appendChild(li);//把li.user插入ul#users中
li.innerHTML = '<img src="4.jpg">\
                <a href="/user/4">yahoo</a>';//用innerHTML插入li.user中的內容。

//若是要用前面的常規方法,則須要下面的一串代碼:
var img = document.createElement("img");//建立img
img.src="4.jpg";//設置img的src
users.appendChild(img);//把img插入到ul#users中
var a = document.createElement("a");//建立a
a.href = "/user/4";//設置a元素的href
a.innerText = "yahoo";//設置a元素的innerText
users.appendChild(a);//把a元素插入到ul#users中
相關文章
相關標籤/搜索