DOM(Document Object Model)

參考書(shū):《JavaScript高級(jí)程序設(shè)計(jì)》


知識(shí)點(diǎn)前提:什么是節(jié)點(diǎn)


Node類型

DOM1級(jí)定義了一個(gè)Node接口怕轿,該接口將DOM中所有節(jié)點(diǎn)類型實(shí)現(xiàn)啸罢。Node接口在JavaScript中是作為Node類型實(shí)現(xiàn)的丑孩;除了IE之外,在其他所有瀏覽器都可以訪問(wèn)到這個(gè)類型。

nodeType

只讀

每個(gè)節(jié)點(diǎn)都有一個(gè)nodeType屬性窟感,有用于表明節(jié)點(diǎn)的類型。節(jié)點(diǎn)類型由在Node類型中定義的下列12個(gè)數(shù)值常量表示歉井,任何節(jié)點(diǎn)類型必占據(jù)一種柿祈。

  • Node.ELEMENT_NODE(1);
  • Node.ATTRIBUTE_NODE(2);
  • Node.TEXT_NODE(3);
  • Node.CDATA_SECTION_NODE(4);
  • Node.ENTITY_REFERENCE_NODE(5);
  • Node.ENTITY_NODE(6);
  • Node.PROCESSING_INSTRUCTION_NODE(7);
  • Node.COMMENT_NODE(8);
  • Node.DOCUMENT_NODE(9);
  • Node.DOCUMENT_TYPE_NODE(10);
  • Node.DOCUMENT_FRAGMENT_NODE(11);
  • Node.NOTATION_NODE(12);

test1

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Fuck!</title>
</head>
<body>
    <h1 id="h">i'm h1</h1>
</body>
<script>
    var h = document.getElementById("h");
    console.log(h.nodeType);                                    // 1
    if (h.nodeType === Node.ELEMENT_NODE) console.log(true);    // true
</script>
</html>

使用Node類型常量來(lái)比較。
由于IE沒(méi)有公開(kāi)Node類型函數(shù)哩至,因此上面代碼在IE中會(huì)導(dǎo)致錯(cuò)誤躏嚎。為確保瀏覽器兼容,最好將nodeType屬性與數(shù)字進(jìn)行比較

test2

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Fuck!</title>
</head>
<body>
    <h1 id="h">i'm h1</h1>
</body>
<script>
    var h = document.getElementById("h");
    if (h.nodeType === 1) console.log(true);    // true
</script>
</html>

不是所有節(jié)點(diǎn)都會(huì)受到瀏覽器支持菩貌,最常用的就是元素和文本節(jié)點(diǎn)卢佣。

MDN —— NodeType


nodaName | nodeValue

nodaName
只讀

nodaValue
可寫(xiě)可讀

使用nodeName和nodeValue可以具體了解節(jié)點(diǎn)信息,這兩個(gè)屬性的值完全取決于節(jié)點(diǎn)的類型箭阶。

可以檢測(cè)節(jié)點(diǎn)類型后在使用其屬性虚茶,下圖列出了不同節(jié)點(diǎn)類型的nodeValue的返回值。


from MDN

所以仇参,對(duì)于element這樣的節(jié)點(diǎn)媳危,返回值都為null。

test3

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Fuck!</title>
</head>
<body>
    <h1 id="h">i'm h1</h1>
</body>
<script>
    var h = document.getElementById("h");
    console.log(h.nodeName+" | "+h.nodeValue);
    // H1 | null
</script>
</html>

可以這樣

test4

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Fuck!</title>
</head>
<body>
    <h1 id="h">i'm h1</h1>
</body>
<script>
    var h = document.getElementById("h").getAttributeNode("id");
    console.log(h);             //  id  [object attr]
    console.log(h.nodeValue);   //  h
</script>
</html>

使用getAttributeNode方法冈敛,輸入屬性名待笑,返回其attribute節(jié)點(diǎn)對(duì)象,然后使用NodeValue方法抓谴,返回值就為實(shí)際屬性值暮蹂。


節(jié)點(diǎn)關(guān)系

文檔中所有的節(jié)點(diǎn)之間都存在這樣或者那樣的關(guān)系。節(jié)點(diǎn)間的各種關(guān)系可以用傳統(tǒng)的家族關(guān)系來(lái)描述癌压,每個(gè)節(jié)點(diǎn)存在childNodes屬性仰泻,其中保存著一個(gè)Nodelist對(duì)象,是一種類數(shù)組對(duì)象滩届,保存一組有序的節(jié)點(diǎn)集侯,可以通過(guò)位置來(lái)訪問(wèn)這些節(jié)點(diǎn)。
雖然可以使用方括號(hào)語(yǔ)法來(lái)訪問(wèn)Nodelist的值,而且這個(gè)對(duì)象也有l(wèi)ength屬性棠枉,但它并不是Array的實(shí)例浓体。Nodelist對(duì)象的獨(dú)特之處在于,它實(shí)際上是基于DOM結(jié)構(gòu)動(dòng)態(tài)執(zhí)行查詢的結(jié)果辈讶,因此DOM結(jié)構(gòu)的變化能夠自動(dòng)反映在Nodelist對(duì)象中命浴。

我們常說(shuō),Nodelist是有生命贱除、有呼吸的對(duì)象生闲,而不是在我們第一次訪問(wèn)它們的某個(gè)瞬間拍攝下來(lái)的一張快照。

test5*

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Fuck!</title>
</head>
<body>
    <div id="div">
        <p>i'm P</p>
        <h1>i'm H1</h1>
    </div>
</body>
<script>
    var html = document.getElementsByTagName("html")[0];
    console.log(html);
</script>
</html>

可以看到其中childNodes屬性里月幌,Nodelist對(duì)象的傳承碍讯,包含了從根目錄下的所有節(jié)點(diǎn)。
其中扯躺,#div的Nodelist里捉兴,是否發(fā)現(xiàn)了有5個(gè)節(jié)點(diǎn),但實(shí)際上源代碼只有2個(gè)元素啊缅帘,其實(shí)[0],[2],[4]所代表的#text是我們?cè)创a換行時(shí)留下的空位轴术,在Nodelist里就用#text來(lái)表示了。
<div id="div"><p>i'm P</p><h1>i'm H1</h1></div>
修改后钦无,將只有兩個(gè)element逗栽。

注意,length屬性表示的是訪問(wèn)Nodelist的那一刻失暂,其中包含的節(jié)點(diǎn)數(shù)量彼宠。
對(duì)于JS函數(shù)內(nèi)部類數(shù)組對(duì)象arguments對(duì)象使用Array.prototype.slice()方法可以將其轉(zhuǎn)換為數(shù)組。而采用同樣的方法弟塞,也可以將Nodelist對(duì)象轉(zhuǎn)換為數(shù)組凭峡。

test6

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Fuck!</title>
</head>
<body>
    <div id="div">
        <p>i'm P</p>
        <h1>i'm H1</h1>
    </div>
</body>
<script>
    var div = document.getElementById("div");

    // 將Nodelist對(duì)象轉(zhuǎn)換為數(shù)組
    var arrayOfNodes = Array.prototype.slice.call(div.childNodes,0);
    
    // 修改數(shù)組不會(huì)反映到Nodelist
    arrayOfNodes.splice(1,0,arrayOfNodes[3]);
    console.log(div.childNodes);
</script>
</html>

為方便演示,縮小范圍决记,只抽取了#div做演示摧冀,
白箭頭即為轉(zhuǎn)換后的真數(shù)組,對(duì)轉(zhuǎn)換后數(shù)組進(jìn)行了一次數(shù)組splice增添節(jié)點(diǎn)操作系宫,那么索昂,是否會(huì)映射到Nodelis上呢?
紅箭頭是Nodelist對(duì)象扩借,看看它椒惨,依然不變。

當(dāng)然潮罪,通過(guò)Nodelist對(duì)象方法添加是可以康谆,后續(xù)~

對(duì)于剛才的Nodelist對(duì)象轉(zhuǎn)換數(shù)組方法领斥,由于在IE8及更早版本將Nodelist實(shí)現(xiàn)為一個(gè)COM對(duì)象,而我們不能像使用JavaScript對(duì)象那樣使用這種對(duì)象沃暗,因此原方法會(huì)導(dǎo)致錯(cuò)誤月洛,要想在IE中Nodelist轉(zhuǎn)換為數(shù)組,必須手動(dòng)枚舉所有成員描睦。
下列代碼在所有瀏覽器均可運(yùn)行:

test7

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Fuck!</title>
</head>
<body>
    <div id="div">
        <p>i'm P</p>
        <h1>i'm H1</h1>
    </div>
</body>
<script>
    function convertToArray(nodes) {
        var array = null;
        try {
            array = Array.prototype.slice.call(nodes,0);    // 針對(duì)非IE瀏覽器
        } catch (ex) {
            array = new Array();
            for (var i=0,len=nodes.length;i<len;i++) {
                array.push(nodes[i]);
            }
        }e
        return array;
    }
    var div = document.getElementById("div");
    console.log(convertToArray(div.childNodes));
</script>
</html>

Array(5) [#text, p, #text, h1, #text]

函數(shù)首先嘗試了創(chuàng)建數(shù)組的最簡(jiǎn)單的方式膊存。如果導(dǎo)致錯(cuò)誤(說(shuō)明在IE8及更早版本中)导而,則通過(guò)try-catch來(lái)捕獲錯(cuò)誤忱叭,然后手動(dòng)創(chuàng)建數(shù)組。
每個(gè)節(jié)點(diǎn)上都有一個(gè)parentNode屬性今艺,該屬性指向文檔樹(shù)中的父節(jié)點(diǎn)韵丑。包含在childNodes列表中的所有節(jié)點(diǎn)都具有相同的父節(jié)點(diǎn),因此它們的parentNode屬性都指向同一個(gè)節(jié)點(diǎn)虚缎。此外撵彻,包含在childNodes列表中的每個(gè)節(jié)點(diǎn)相互之間都是同胞節(jié)點(diǎn)(siblingNode)。通過(guò)使用列表中的每個(gè)節(jié)點(diǎn)的previousSibling和nextSibling屬性实牡,可以訪問(wèn)同一列表中的其他節(jié)點(diǎn)陌僵。

關(guān)于節(jié)點(diǎn)關(guān)系,主要就是子節(jié)點(diǎn)创坞、節(jié)點(diǎn)碗短、父節(jié)點(diǎn)之間的定位關(guān)系。


test8

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Fuck!</title>
</head>
<body>
    <div id="div"><p id="p">i'm P</p><h1 id="h1">i'm H1</h1></div>
</body>
<script>
    var div = document.getElementById("div");
    var p = document.getElementById("p");
    var h = document.getElementById("h1"); 


    console.log(div.firstChild);        // 選中#div的第一個(gè)子元素:p#p
    console.log(div.lastChild);         // 選中#div的最后一個(gè)子元素:h1#h1

    console.log(p.nextSibling);         // 選中#p的下一個(gè)兄弟元素:h1#h1
    console.log(h.previousSibling);     // 選中#h1的上一個(gè)兄弟元素:p#p

    console.log(p.parentNode);          // 選中#p的父元素:div#div
</script>
</html>

在反映這些關(guān)系的所有屬性當(dāng)中题涨,childNodes屬性與其他屬性相比更方便一些偎谁,因?yàn)橹豁毷褂煤?jiǎn)單的關(guān)系指針,就可以通過(guò)它訪問(wèn)文檔樹(shù)中的任何節(jié)點(diǎn)纲堵。另外巡雨,hasChildNodes()也是一個(gè)非常有用的方法,這個(gè)方法在節(jié)點(diǎn)包含一或多個(gè)子節(jié)點(diǎn)的情況下返回true席函;應(yīng)該說(shuō)铐望,這是比查詢childNodes列表的length屬性更簡(jiǎn)單的方法。
所有節(jié)點(diǎn)都有的最后一個(gè)屬性時(shí)ownerDocument茂附,該屬性指向表示整個(gè)文檔的文檔節(jié)點(diǎn)正蛙。這種關(guān)系表示的是任何節(jié)點(diǎn)都屬于它所在的文檔,任何節(jié)點(diǎn)都不能同時(shí)存在與兩個(gè)或多個(gè)文檔中何之。通過(guò)這個(gè)屬性跟畅,我們可以不必在節(jié)點(diǎn)層次中通過(guò)層層回溯到達(dá)頂端,而是可以直接訪問(wèn)文檔節(jié)點(diǎn)溶推。


操作節(jié)點(diǎn)

因?yàn)殛P(guān)系指針都是只讀的徊件,所以DOM提供了一些操作節(jié)點(diǎn)的方法奸攻。其中,最常用的方法時(shí)appendChild()虱痕,用于向childNodes列表的末尾添加一個(gè)節(jié)點(diǎn)睹耐。添加節(jié)點(diǎn)后,childNodes的新增節(jié)點(diǎn)部翘、父節(jié)點(diǎn)及以前的最后一個(gè)子節(jié)點(diǎn)的關(guān)系指針都會(huì)相應(yīng)的得到更新(因?yàn)閏hildNodes屬性里的Nodelist對(duì)象更新了)硝训。更新完成后,appendChild()返回新增的節(jié)點(diǎn)新思。

test9

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Fuck!</title>
</head>
<body>
    <div id="div">
        <p id="p">i'm P</p>
        <h1 id="h1">i'm H1</h1>
    </div>
</body>
<script>
    var h6 = document.createElement("h6");
    var div = document.getElementById("div");

    var returnNode = div.appendChild(h6);
    console.log(returnNode === h6);         // true
    console.log(div.lastChild === h6);      // true
</script>
</html>

如果傳入到appendChild()中的節(jié)點(diǎn)已經(jīng)是文檔中的一部分了窖梁,那結(jié)果就是將該節(jié)點(diǎn)從原來(lái)的位置轉(zhuǎn)移到新位置。即使可以將DOM數(shù)看成是由一系列指針連接起來(lái)的 夹囚,但任何DOM節(jié)點(diǎn)也不能同時(shí)出現(xiàn)在文檔中的多個(gè)位置上纵刘。因此,如果在調(diào)用appenChild()時(shí)傳入了父節(jié)點(diǎn)的第一個(gè)子節(jié)點(diǎn)荸哟,那么該節(jié)點(diǎn)就會(huì)成為父節(jié)點(diǎn)的最后一個(gè)子節(jié)點(diǎn)假哎。

test10

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Fuck!</title>
</head>
<body>
    <div id="div">
        <p id="p">i'm P</p>
    </div>
</body>
<script>
    var div = document.getElementById("div");
    var returnNode = div.appendChild(div.firstChild);

    console.log(returnNode === div.firstChild);     // false
    console.log(returnNode === div.lastChild);      // true

</script>
</html>

如果需要把節(jié)點(diǎn)放在childNodes列表中某個(gè)特定的位置上,而不是放在末尾鞍历,那么可以使用inserBefore()方法舵抹。這個(gè)方法接受兩個(gè)參數(shù):要插入的節(jié)點(diǎn)和作為參照的節(jié)點(diǎn)。插入節(jié)點(diǎn)后劣砍,被插入的節(jié)點(diǎn)會(huì)變成參照節(jié)點(diǎn)的前一個(gè)同胞節(jié)點(diǎn)(preivousSibling)惧蛹,同時(shí)被方法返回,如果參照節(jié)點(diǎn)是null秆剪,則insertBefore()與appendChild()執(zhí)行相同的操作赊淑。

test11

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Fuck!</title>
</head>
<body>
    <div id="div"><p id="p">i'm P</p><h1 id="h1">i'm H1</h1></div>
</body>
<script>
    var div = document.getElementById("div");
    var h1 = document.getElementById("h1");
    var p = document.getElementById("p");
    console.log(div);

    // 創(chuàng)建的新節(jié)點(diǎn)h6
    var h6 = document.createElement("h6");
    var text = document.createTextNode("i'm h6");
    h6.appendChild(text);

    // 將新創(chuàng)建的h6節(jié)點(diǎn)插入到h1之前
    div.insertBefore(h6,h1);
    console.log(h1.previousSibling === h6);     // true
    // p > h6 > h1
    
    // 將h1插入到p之前,同時(shí)h6位置為最后一個(gè)子節(jié)點(diǎn)
    div.insertBefore(h6,p);
    console.log(p.previousSibling === h6);      // true 
    console.log(div.firstChild === h6);         // true
    console.log(div.lastChild === h1);          // true
     
</script>
</html>
注意仅讽,如果將代碼換行陶缺,保證可讀性的同時(shí),會(huì)使Nodelist對(duì)象增加若干的#text節(jié)點(diǎn)洁灵,這是換行導(dǎo)致的饱岸。

如若要替換節(jié)點(diǎn)可使用replaceChild()方法
方法接受兩個(gè)參數(shù):要插入的節(jié)點(diǎn),要替換的節(jié)點(diǎn)徽千。要替換的節(jié)點(diǎn)將由這個(gè)方法返回并從文檔樹(shù)中移除苫费,同時(shí)插入的節(jié)點(diǎn)占據(jù)其位置。

test12

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Fuck!</title>
</head>
<body>
    <div id="div"><p id="p">i'm P</p><h1 id="h1">i'm H1</h1>
    </div>
</body>
<script>
    var div = document.getElementById("div");
    var h1 = document.getElementById("h1");
    var p = document.getElementById("p");

    // 創(chuàng)建一個(gè)新節(jié)點(diǎn)h3
    var h3 = document.createElement("h3");
    h3.appendChild(document.createTextNode("i'm h3"));

    // 替換p節(jié)點(diǎn)
    var returnNode = div.replaceChild(h3,p);
    console.log(returnNode);            // p#p
    
</script>
</html>

使用replaceChild()插入一個(gè)節(jié)點(diǎn)時(shí)双抽,該節(jié)點(diǎn)所有關(guān)系指針都會(huì)從被它替換的節(jié)點(diǎn)賦值過(guò)來(lái)百框,盡管從技術(shù)上講,被替換的節(jié)點(diǎn)還在文檔中牍汹,但它在文檔中已經(jīng)沒(méi)有了自己的位置铐维。

如果只想移除而非替換節(jié)點(diǎn)柬泽,可以使用removeChild()方法。
方法接受一個(gè)參數(shù)嫁蛇,即要移除的節(jié)點(diǎn)锨并。被移除的節(jié)點(diǎn)將成為方法的返回值。
test13

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Fuck!</title>
</head>
<body>
    <div id="div"><p id="p">i'm P</p><h1 id="h1">i'm H1</h1>
    </div>
</body>
<script>
    var div = document.getElementById("div");
    var h1 = document.getElementById("h1");
    var p = document.getElementById("p");

    // 創(chuàng)建一個(gè)新節(jié)點(diǎn)h3
    var h3 = document.createElement("h3");
    h3.appendChild(document.createTextNode("i'm h3"));

    // 替換p節(jié)點(diǎn)
    var returnNode = div.replaceChild(h3,p);
    console.log(returnNode);            // p#p

    // 移除第一個(gè)節(jié)點(diǎn)
    var formerFirstChild = div.removeChild(div.firstChild);
    console.log(formerFirstChild);      // h3
    console.log(div.firstChild);        // h1#h1
</script>
</html>

有兩個(gè)方法是所有類型節(jié)點(diǎn)都有的睬棚。

  • cloneNode()

  • normalize()

cloneNode()方法接受一個(gè)布爾值參數(shù)第煮,表示是否執(zhí)行深復(fù)制。參數(shù)為true情況下抑党,執(zhí)行深復(fù)制包警,也就是復(fù)制節(jié)及其整個(gè)子節(jié)點(diǎn)樹(shù);在參數(shù)為false情況下新荤,執(zhí)行潛復(fù)制揽趾,即只復(fù)制節(jié)點(diǎn)本身台汇。復(fù)制后返回的節(jié)點(diǎn)副本屬于文檔所有苛骨,但并沒(méi)有為它指定父節(jié)點(diǎn)。因此這個(gè)節(jié)點(diǎn)副本就成為了一個(gè)“孤兒”苟呐,除非通過(guò)appedChild痒芝,insertBefore,replaceChild將它添加到文檔中牵素。

test14

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Fuck!</title>
</head>
<body>
    <ul>
        <li>item 1</li>
        <li>item 2</li>
        <li>item 3</li>
    </ul>
</body>
<script>
    var ul = document.getElementsByTagName("ul")[0];

    var deepList = ul.cloneNode(true);
    var shallow = ul.cloneNode(false);

    console.log(deepList.childNodes.length);    //  7 4個(gè)空隙严衬,三個(gè)元素,長(zhǎng)度為7
    console.log(shallow.childNodes.length);     //  0 
</script>
</html>

cloneNode()不會(huì)賦值添加到DOM節(jié)點(diǎn)中的JavaScript屬性笆呆,例如事件處理程序等请琳,這個(gè)方法只復(fù)制特性、子節(jié)點(diǎn)(true)赠幕,其他一切都不會(huì)復(fù)制俄精。


normalize()

這個(gè)方法唯一作用就是處理文檔樹(shù)中的文本節(jié)點(diǎn)。
由于解析器的實(shí)現(xiàn)或者DOM操作等原因榕堰,可能會(huì)出現(xiàn)文本節(jié)點(diǎn)或者不包含文本竖慧,或者接連出現(xiàn)兩個(gè)文本節(jié)點(diǎn)的情況。
當(dāng)在某個(gè)節(jié)點(diǎn)上調(diào)用這個(gè)方法時(shí)逆屡,就會(huì)在該節(jié)點(diǎn)的后代節(jié)點(diǎn)中查找上述兩種情況圾旨。如果找到空白文本節(jié)點(diǎn),則刪除它魏蔗,如果找到相鄰的文本節(jié)點(diǎn)砍的,則將它們合并為一個(gè)文本節(jié)點(diǎn)。


Document類型

JavaScript通過(guò)Document類型表示文檔莺治。在瀏覽器匯總廓鞠,document對(duì)象是HTMLDocument(繼承自Document類型)的一個(gè)實(shí)例味混,表示整個(gè)HTML頁(yè)面。而且诫惭,document對(duì)象是window對(duì)象的一個(gè)屬性翁锡,因此可以將其作為全局對(duì)象來(lái)訪問(wèn)。

window.document === document // true

Document節(jié)點(diǎn)具有下列特征:

  • nodeType的值為:9
  • nodeName的值為:"#document"
  • nodeValue的值為:null
  • parentNode的值為:null
  • 其子節(jié)點(diǎn)可能是一個(gè)DocumentType(最多一個(gè))夕土、Element(最多一個(gè))馆衔、ProcessingInstruction或Comment。

Document類型可以表示HTML頁(yè)面或者其他基于XML的文檔怨绣。不過(guò)角溃,最常見(jiàn)的應(yīng)用還是作為HTMLDocument實(shí)例的document對(duì)象。通過(guò)這個(gè)文檔對(duì)象篮撑,不僅可以取得與頁(yè)面有關(guān)的信息减细,而且還能操作頁(yè)面的外觀及其底層結(jié)構(gòu)。

1.文檔的子節(jié)點(diǎn)

雖然DOM標(biāo)準(zhǔn)規(guī)定Document節(jié)點(diǎn)的子節(jié)點(diǎn)可以是DocumentType赢笨、Element未蝌、ProcessingIn-struction或Comment,但還有兩個(gè)內(nèi)置的訪問(wèn)其子節(jié)點(diǎn)的快捷方式茧妒。第一個(gè)就是documentElement屬性萧吠,該屬性始終指向HTML頁(yè)面中的<html>元素。另一個(gè)就是通過(guò)childNodes列表訪問(wèn)文檔元素桐筏,但通過(guò)documentElement屬性則能更快捷纸型、直接的訪問(wèn)元素。

<html>
    <body>
        
    </body>
</html>

這個(gè)頁(yè)面經(jīng)瀏覽器解析后梅忌,其文檔中只包含一個(gè)子節(jié)點(diǎn)狰腌,即<html>元素∧恋可以通過(guò)documentElement或childNodes列表來(lái)訪問(wèn)這個(gè)元素琼腔。

        var html = document.documentElement;            // 取得對(duì)<html>的引用
        console.log(html === document.childNodes[0]);   // true
        console.log(html === document.firstChild);      // true

documentElement、firstChild和childNodes[0]的值相同蹋笼。展姐,都指向<html>元素。

作為HTMLDocument的實(shí)例剖毯,document對(duì)象還有一個(gè)body屬性圾笨,直接指向<body>元素。因?yàn)殚_(kāi)發(fā)人員經(jīng)常要使用這個(gè)元素逊谋,所以document.body在JS代碼匯總出現(xiàn)的頻率很高擂达。
var body = document.body;
所有瀏覽器都支持document.documentElement和document.body屬性。
Document另一個(gè)可能的子節(jié)點(diǎn)就是DocumentType胶滋。通常將<!DOCTYPE>標(biāo)簽看成一個(gè)與文檔其他部分不同的實(shí)體板鬓,可以通過(guò)doctype屬性來(lái)訪問(wèn)它的信息悲敷。
var doctype = document.doctype;

類似的,還有如下功能方法俭令,取得文檔信息后德。

取得文檔標(biāo)題
var originalTitle = document.title;
設(shè)置文檔標(biāo)題
document.title = "New page ttile";

網(wǎng)頁(yè)請(qǐng)求相關(guān)方法;
  • URL:屬性中包含頁(yè)面完整的URL(即地址欄中顯示的URL)
  • domain:只包含頁(yè)面的域名
  • referrer:保存鏈接到當(dāng)前頁(yè)面的頁(yè)面的URL(從哪到這的)抄腔,referrer屬性可能包含空字符串瓢湃。所有信息都存在請(qǐng)求HTTP頭部,只不過(guò)通過(guò)這些屬性讓我們能夠在JavaScript中訪問(wèn)它們而已赫蛇。
//取得完整URL
var url = document.URL;

//取得域名
var domain = document.domain;

//取得來(lái)源頁(yè)面的URL
var referrer = document.referrer;

URL和domain屬性是相互關(guān)聯(lián)的绵患。例如,如果document.URL為http://www.wrox.com/WileyCDA/悟耘,那么document.domain就是www.wrox.com落蝙。

這三個(gè)屬性中,只有domain是可以設(shè)置的暂幼,但由于安全方面限制筏勒,并非可以給domain設(shè)置任何值。如果URL包含一個(gè)子域名粟誓,例如p2p.wrox.com奏寨,那么就只能將domain設(shè)置為wrox.com。不能將這個(gè)屬性設(shè)置為URL中不包含的域鹰服。

        // 假設(shè)頁(yè)面來(lái)自:p2p.wrox.com
        document.domain = "wrox.com";       // 成功
        document.domain = "nczonline.net";  // 出粗!

當(dāng)頁(yè)面中包含來(lái)自其他子域的框架或內(nèi)嵌框架時(shí)揽咕,能夠設(shè)置domain就非常方便了悲酷。由于跨域安全限制,來(lái)自不同子域的頁(yè)面無(wú)法通過(guò)JavaScript通信亲善。而通過(guò)將每個(gè)頁(yè)面的document.domain設(shè)置為相同的值设易,這些頁(yè)面就可以互相訪問(wèn)對(duì)方包含的JavaScript對(duì)象了。例如蛹头,假設(shè)有一個(gè)頁(yè)面加載自www.wrox.com顿肺,其中包含一個(gè)內(nèi)嵌框架,框架內(nèi)的頁(yè)面加載來(lái)自p2p.wrox.com渣蜗。由于document.domain字符串不一樣屠尊,內(nèi)外兩個(gè)頁(yè)面之間無(wú)法相互訪問(wèn)對(duì)方的JavaScript對(duì)象。但如果將兩個(gè)頁(yè)面的document.domain值設(shè)置為wrox.com耕拷,他們之間就可以通信了讼昆。

瀏覽器對(duì)domain屬性還有一個(gè)限制,即如果域名一開(kāi)始是松散的骚烧,那么不能將它設(shè)置為緊繃的浸赫。換句話說(shuō)闰围,在將document.domain設(shè)置為wrox.com之后,不能再將其設(shè)置回p2p.wrox.com既峡,否認(rèn)導(dǎo)致錯(cuò)誤羡榴。

// 假設(shè)頁(yè)面來(lái)自于p2p.wrox.com域
document.domain = "wrox.com";    // 松散的(成功)
document.domain = "p2p.wrox.com"    // 緊繃的(出錯(cuò)!)

查找元素

Document類型提供的兩個(gè)方法:

  • getElementById()
  • getElementsByTagName()

第一個(gè)方法运敢,接受一個(gè)參數(shù):要取得的元素ID炕矮,如果找到相應(yīng)的元素則返回該元素,如果不存在帶有相應(yīng)的ID的元素者冤,則返回null肤视。注意,這里的ID必須與頁(yè)面中的元素的ID特性嚴(yán)格匹配涉枫,包括大小寫(xiě)邢滑。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <div id="myDiv"></div>
    <script>
        var div = document.getElementById("myDiv");     // 取得對(duì)<div>元素的引用
    </script>
</body>
</html>

但是,在IE7下和更早版本的瀏覽器都將返回null愿汰。
var div = document.getElementById("mydiv");
IE8及較早版本不區(qū)分ID的大小寫(xiě)困后,因此"myDiv"和"mydiv"會(huì)被當(dāng)作相同的元素ID。
如果頁(yè)面中多個(gè)元素的ID值相同衬廷,getElmentById()只返回文檔中第一次出現(xiàn)的元素摇予。

document.getElementsByTagName()
接受一個(gè)參數(shù),既要取得元素的標(biāo)簽名,返回的是包含零或多個(gè)元素的Nodelist芋膘。在HTML文檔中车柠,這個(gè)方法會(huì)返回一個(gè)HTMLCollection對(duì)象,作為一個(gè)動(dòng)態(tài)集合酗宋,該對(duì)象與Nodelist對(duì)象非常類似。例如疆拘,下列代碼回取得頁(yè)面中所有的<img>元素蜕猫,并返回一個(gè)HTMLCollection。
var images = document.getElementsByTagName("img");
這行代碼會(huì)將一個(gè)HTMLCollection對(duì)象保存在images變量中哎迄。與Nodelist對(duì)象類似回右,可以使用方括號(hào)語(yǔ)法或item()方法來(lái)訪問(wèn)對(duì)象中的項(xiàng)。而這個(gè)對(duì)象中元素的數(shù)量則可以通過(guò)其length屬性取得漱挚。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <div id="myDiv"></div>
    <script>
        var divs = document.getElementsByTagName("div");
        console.log(divs.length);       // 1    輸出div的數(shù)量
        console.log(divs[0].id);            // myDiv    輸出第一個(gè)div元素的ID特性
        console.log(divs.item(0).id);   // myDiv    輸出第一個(gè)div元素的ID特性
    </script>
</body>
</html>

HTMLCollection對(duì)象還有一個(gè)方法翔烁,叫做namedItem(),使用這個(gè)方法可以通過(guò)元素的那么name特性取得集合中的項(xiàng)棱烂。例如租漂,假設(shè)上面提到的頁(yè)面中包含如下<div>元素
<div id="myDiv" name="myDiv">
那么可以通過(guò)如下方式從divs變量中取得這個(gè)<div>元素。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <div id="myDiv" name="myDiv"></div>
    <script>
        var divs = document.getElementsByTagName("div");
        var div = divs.namedItem("myDiv");
        console.log(div);       // div#myDiv
    </script>
</body>
</html>

咋提供按索引訪問(wèn)項(xiàng)的基礎(chǔ)上,HTMLCollection還支持按名稱訪問(wèn)項(xiàng)哩治,這就為我們?nèi)〉脤?shí)際想要的元素提供了便利秃踩。而且,對(duì)命名的項(xiàng)也可以使用方括號(hào)語(yǔ)法來(lái)訪問(wèn)业筏。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <div id="myDiv"></div>
    <script>
        var divs = document.getElementsByTagName("div");
        var div = divs["myDiv"];
        console.log(div);   // div#myDiv

    </script>
</body>
</html>

第三個(gè)方法憔杨,也就是只有HTMLDocument類型才有的方法,是getElementsByName()蒜胖,顧名思義消别,方法會(huì)返回帶有給定name特性的所有元素。最常使用getElementsByName()方法的情況是取得單選按鈕台谢。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <fieldset>
        <legend>Which color do you prefer?</legend>
        <ul>
            <li>
                <input type="radio" value="red" name="color" id="colorRed">
                <label for="colorRed">red</label>
            </li>
            <li>
                <input type="radio" value="green" name="color" id="colorGreen">
                <label for="colorGreen">Green</label>
            </li>
            <li>
                <input type="radio" value="blue" name="color" id="colorBlue">
                <label for="colorBlue">Blue</label>
            </li>
        </ul>
    </fieldset>

    <script>
        var radios = document.getElementsByName("color");
    </script>
</body>
</html>

所有的單選按鈕的name特性值相同都是color寻狂,但它們的ID不同,ID作用在于將label元素應(yīng)用到每個(gè)單選按鈕朋沮,而name特性則用以確保三個(gè)值中只有一個(gè)被發(fā)送給瀏覽器蛇券。這樣,我們?nèi)〉盟袉芜x按鈕樊拓。

特殊集合

除了屬性和方法纠亚,document對(duì)象還有一些特殊的集合,這些集合都是HTMLCollection對(duì)象筋夏,為訪問(wèn)文檔常用的部分提供了快捷方式蒂胞,包括:

  • document.anchors,包含文檔中所有帶name特性的<a>元素
  • document.applets条篷,包含文檔中所有的<applet>元素骗随,很少使用。
  • document.forms拥娄,包含所有的<form>元素
  • document.images蚊锹,包含所有的<img>元素
  • document.links,包含文檔中所有的帶href特性的<a>元素稚瘾。

Element類型

訪問(wèn)元素的標(biāo)簽名,使用nodeName屬性姚炕,也可以使用tagName屬性摊欠;這兩個(gè)屬性會(huì)返回相同的值,使用后者主要是為了清晰可見(jiàn)柱宦。
<div id="myDiv"></div>
可以先這樣取得元素及其標(biāo)簽名:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <div id="myDiv"></div>
    <script>
        var div = document.getElementById("myDiv");
        console.log(div.tagName);           // "DIV"
        console.log(div.tagName === div.nodeName);  // true
    </script>
</body>
</html>

所有的HTML元素都由HTMLElement類型表示些椒,不是直接通過(guò)這個(gè)類型,也是通過(guò)它的子類型表示掸刊。HTMLElement類型直接繼承自Element并添加了一些屬性免糕。添加的這些屬性分別對(duì)應(yīng)于每個(gè)HTML元素中都存在的下列標(biāo)準(zhǔn)特性。

  • id,元素在文檔中的唯一標(biāo)識(shí)符
  • title石窑,元素附加說(shuō)明信息牌芋,通過(guò)工具提示條顯示
  • lang,元素語(yǔ)言代碼
  • dir松逊,語(yǔ)言方向躺屁,ltr(left to right),rtl(right to left)经宏,很少使用犀暑。
  • className,與元素class屬性對(duì)應(yīng)烁兰。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>

    <div id="myDiv" class="bd" title="Body text" lang="en" dir="ltr"></div>

    <script>
        var div = document.getElementById("myDiv");

        console.log(div.id);            // myDiv
        console.log(div.className);     // bd
        console.log(div.title);         // Body text
        console.log(div.lang);          // en
        console.log(div.dir);           // ltr
    </script>
</body>
</html>

也可以為每個(gè)屬性賦值耐亏,修改對(duì)應(yīng)屬性的特性。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>

    <div id="myDiv" class="bd" title="Body text" lang="en" dir="ltr"></div>

    <script>
        var div = document.getElementById("myDiv");

        div.id = "someOtherId";
        div.className = "ft";
        div.title = "Some other text";
        div.lang = "fr";
        div.dir = "rtl";

        console.log(div.id);        
        console.log(div.className); 
        console.log(div.title);     
        console.log(div.lang);      
        console.log(div.dir);           
        /*
        someOtherId
        ft
        Some other text
        fr
        rtl
        */
    </script>
</body>
</html>

*取得特性

getAttribute()

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>

    <div id="myDiv" class="bd" title="Body text" lang="en" dir="ltr"></div>

    <script>
        var div = document.getElementById("myDiv");

        console.log(div.getAttribute("id"));    
        console.log(div.getAttribute("class")); 
        console.log(div.getAttribute("title"));     
        console.log(div.getAttribute("lang"));      
        console.log(div.getAttribute("dir"));           
        /*
        myDiv
        bd
        Body text
        en
        ltr
        */
    </script>
</body>
</html>

傳遞給方法的特性名與實(shí)際的特性名相同沪斟,因此要想得到class的特性值广辰,應(yīng)該傳入class而不是className,后者只有在通過(guò)對(duì)象屬性訪問(wèn)特性時(shí)采用币喧。如果給定名稱特性名不存在轨域,則返回null。

當(dāng)然杀餐,你可以添加自定義特性干发,標(biāo)準(zhǔn)HTML中沒(méi)有的特性。
<div id="myDiv" my_special_attrbute="hello!"></div>
這個(gè)元素包含一個(gè)名為my_special_attrbute的自定義特性史翘,值為hello!枉长,可以像取得其他特性一樣取得這個(gè)值。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>

    <div id="myDiv" my_special_attrbute="hello!"></div>

    <script>
        var div = document.getElementById("myDiv");
        var value = div.getAttribute("my_special_attrbute");
        console.log(value);     // hello!
    </script>
</body>
</html>

不過(guò)琼讽,只有公認(rèn)的特性才會(huì)以屬性的形式添加到DOM對(duì)象中
<div id="myDiv" align="left" my_special_attribute="hello!"></div>
因?yàn)閕d和align在HTML中是<div>的公認(rèn)特性必峰,因此該元素的DOM對(duì)象中也將存在對(duì)應(yīng)的屬性。不過(guò)钻蹬,自定義特性my_special_attribute在Safari吼蚁、Opera、Chrome及Firefox是不存在的问欠;但I(xiàn)E卻會(huì)為自定義特性也創(chuàng)建屬性肝匆。

        console.log(div.id);                    // "myDiv"
        console.log(div.my_special_attribute);  // undefined(IE除外)
        console.log(div.align);                 // "left"

有兩類特殊的特性,它們雖然有對(duì)應(yīng)的屬性名顺献,但屬性值與通過(guò)getAttribute()返回的值并不相同旗国,第一類是style,通過(guò)CSS為元素指定形式注整。通過(guò)getAttribute()訪問(wèn)時(shí)能曾,返回的style特性值中包含的是CSS文本度硝,而通過(guò)屬性來(lái)訪問(wèn)它則返回一個(gè)對(duì)象。由于style屬性用于以編程方式訪問(wèn)元素樣式的寿冕,因此并沒(méi)有映射到style屬性蕊程。

第二類與眾不同的特性時(shí)onclick這樣的事件處理程序,當(dāng)在元素上使用時(shí)蚂斤,onclick特性中包含的是JavaScript代碼存捺,如果通過(guò)getAttribute()訪問(wèn),則會(huì)返回相應(yīng)的代碼的字符串曙蒸。而在訪問(wèn)onclick屬性時(shí)捌治,則會(huì)返回一個(gè)JavaScript函數(shù)(如果未指定,返回null)這是因?yàn)閛nclick及其他事件處理程序?qū)傩员旧砭蛻?yīng)該被賦予函數(shù)值纽窟。

由于這些差別肖油,通過(guò)JavaScript編程方式操作DOM時(shí),開(kāi)發(fā)者經(jīng)常不使用getAttribute()臂港,而是只使用對(duì)象屬性森枪,只有在取得自定義特性值情況下,才會(huì)使用getAttribute()方法审孽。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<style>

</style>
<body>

    <div id="myDiv" style="background-color:red;width:100px;height:100px"></div>

    <script>
        var div = document.getElementById("myDiv");
        console.log(div.getAttribute("style"));     // background-color:red;width:100px;height:100px
        console.log(div.style);// CSSStyleDeclaration {0: "background-color", 1: "width", 2: "height", alignContent: "", alignItems: "", alignSelf: "", alignmentBaseline: "", all: "", …}
    </script>
</body>
</html>

設(shè)置特性
與getAttribute()對(duì)應(yīng)的方法是setAttribute()县袱,這個(gè)方法接受兩個(gè)參數(shù):要設(shè)置的特性名和值。如果特性已經(jīng)存在佑力,setAttribute()會(huì)以指定的值替換現(xiàn)有的值式散;如果特性不存在,setAttribute()則創(chuàng)建該屬性并設(shè)置相應(yīng)的值打颤。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<style>

</style>
<body>

    <div></div>

    <script>
        var div = document.getElementsByTagName("div")[0];

        div.setAttribute("id","someOtherId");
        div.setAttribute("class","ft");
        div.setAttribute("title","Some other text");        
        div.setAttribute("lang","fr");
        div.setAttribute("dir","rtl");
    </script>
</body>
</html>

通過(guò)方法既可以操作HTML特性暴拄,也可以操作自定義特性。通過(guò)這個(gè)方法設(shè)置的特性名會(huì)統(tǒng)一轉(zhuǎn)換為小寫(xiě)形式编饺,即ID最終會(huì)成為id乖篷。

不過(guò),添加自定義屬性透且,該屬性不會(huì)自動(dòng)成為元素的特性撕蔼。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<style>

</style>
<body>

    <div></div>

    <script>
        var div = document.getElementsByTagName("div")[0];
        
        div.mycolor = "red";
        console.log(div.getAttribute("mycolor"));       // null
    </script>
</body>
</html>

attributes屬性

Element類型是使用attributes屬性的唯一一個(gè)DOM節(jié)點(diǎn)類型。attributes屬性中包含一個(gè)NamedNodeMap秽誊,與Nodelist類似罕邀,也是一個(gè)動(dòng)態(tài)集合。元素的每一個(gè)特性都由一個(gè)Attr節(jié)點(diǎn)表示养距,每個(gè)節(jié)點(diǎn)都保存在NamedNodeMap對(duì)象中。NamedNodeMap擁有下列方法:

  • getNamedItem(name):返回nodeName屬性等于name的節(jié)點(diǎn)日熬;
  • removeNamedItem(name):從列表中移除nodeName屬性等于name的節(jié)點(diǎn)棍厌;
  • setNamedItem(node):向列表中添加節(jié)點(diǎn),以節(jié)點(diǎn)的nodeName屬性為索引;
  • item(pos):返回位于數(shù)字pos位置處的節(jié)點(diǎn)耘纱。

attributes屬性中包含一系列節(jié)點(diǎn)敬肚,每個(gè)節(jié)點(diǎn)的nodeName就是特性的名稱,而節(jié)點(diǎn)的nodeValue就是特性的值束析。要取得元素的id特性艳馒,可以:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<style>

</style>
<body>

    <div id="myDiv"></div>

    <script>
        var div = document.getElementById("myDiv");
        var id = div.attributes.getNamedItem("id").nodeValue;
        console.log(id);    // myDiv
    </script>
</body>
</html>

或者使用方括號(hào)語(yǔ)法通過(guò)特性名稱訪問(wèn)節(jié)點(diǎn)的簡(jiǎn)寫(xiě)方式。
var id = div.attributes["id"].nodeValue;
也可以通過(guò)以上的方法設(shè)置特性的值员寇。
div.attributes["id"].nodeValue = "someOtherId";

一般來(lái)說(shuō)弄慰,attributes的方法不夠方便,更多的會(huì)使用getAttribute()蝶锋、removeAttribute()和setAttribute()方法陆爽。
不過(guò),如果想要遍歷元素特性扳缕,attributes屬性可以派上用場(chǎng)慌闭。在需要將DOM結(jié)構(gòu)序列化為XML或者HTML字符串時(shí),多數(shù)都會(huì)涉及遍歷元素特性躯舔。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<style>
</style>

<body>

    <div id="myDiv" class="div_class" align="left" name="DIV"></div>

    <script>

        var div = document.getElementById("myDiv");

        function outputAttributes(element) {
            var attrName;
            var attrValue;
            var pairs = [];
            var len = element.attributes.length;

            for (var i = 0; i < len; i++) {
                attrName = element.attributes[i].nodeName;
                attrValue = element.attributes[i].nodeValue;
                pairs.push(attrName + '=\"' + attrValue + '\"');
            }
            return pairs;
        }
        
        console.log(outputAttributes(div));
    </script>
</body>
</html>

針對(duì)attributes對(duì)象中的特性驴剔,不同瀏覽器返回的順序不同。這些特性在XML和HTML代碼中出現(xiàn)的先后順序粥庄,不一定與它們出現(xiàn)在attributes對(duì)象中的順序一致丧失。
IE7及更早版本會(huì)返回HTML元素中所有可能的特性,包括沒(méi)有指定的特性飒赃。換句話說(shuō)利花,返回100多個(gè)特性的情況會(huì)很常見(jiàn)。

創(chuàng)建元素
var div = document.createElement("div");
使用createElement()方法創(chuàng)建新元素的同時(shí)载佳,也為新元素設(shè)置了ownerDocument屬性炒事。此時(shí),還可以操作元素的特性蔫慧,為它添加更多子節(jié)點(diǎn)挠乳,以及執(zhí)行其他操作。

        div.id = "myNewDiv";
        div.className = "box";

然后添加到文檔數(shù)中姑躲∷铮可以使用appendChild()、insertBefore()黍析、replaceChild()方法卖怜。

document.body.appendChild(div);

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市阐枣,隨后出現(xiàn)的幾起案子马靠,更是在濱河造成了極大的恐慌奄抽,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件甩鳄,死亡現(xiàn)場(chǎng)離奇詭異逞度,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)妙啃,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門档泽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人揖赴,你說(shuō)我怎么就攤上這事馆匿。” “怎么了储笑?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵甜熔,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我突倍,道長(zhǎng)腔稀,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任羽历,我火速辦了婚禮焊虏,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘秕磷。我一直安慰自己诵闭,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布澎嚣。 她就那樣靜靜地躺著疏尿,像睡著了一般。 火紅的嫁衣襯著肌膚如雪易桃。 梳的紋絲不亂的頭發(fā)上褥琐,一...
    開(kāi)封第一講書(shū)人閱讀 51,125評(píng)論 1 297
  • 那天,我揣著相機(jī)與錄音晤郑,去河邊找鬼敌呈。 笑死,一個(gè)胖子當(dāng)著我的面吹牛造寝,可吹牛的內(nèi)容都是我干的磕洪。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼诫龙,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼析显!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起签赃,我...
    開(kāi)封第一講書(shū)人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤叫榕,失蹤者是張志新(化名)和其女友劉穎浑侥,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體晰绎,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡括丁,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年荞下,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片史飞。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡尖昏,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出构资,到底是詐尸還是另有隱情抽诉,我是刑警寧澤,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布吐绵,位于F島的核電站迹淌,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏己单。R本人自食惡果不足惜唉窃,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望纹笼。 院中可真熱鬧纹份,春花似錦、人聲如沸廷痘。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)笋额。三九已至元暴,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間鳞陨,已是汗流浹背昨寞。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留厦滤,地道東北人援岩。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓掏导,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親添瓷。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • ??DOM(文檔對(duì)象模型)是針對(duì) HTML 和 XML 文檔的一個(gè) API(應(yīng)用程序編程接口)惰聂。 ??DOM 描繪...
    霜天曉閱讀 3,640評(píng)論 0 7
  • 本章內(nèi)容 理解包含不同層次節(jié)點(diǎn)的 DOM 使用不同的節(jié)點(diǎn)類型 克服瀏覽器兼容性問(wèn)題及各種陷阱 DOM 是針對(duì) HT...
    悶油瓶小張閱讀 638評(píng)論 0 1
  • DOM(文檔對(duì)象模型)是針對(duì) HTML 和 XML 文檔的一個(gè) API搓幌。DOM 描繪了一個(gè)層次化的節(jié)點(diǎn)樹(shù)迅箩,允許開(kāi)發(fā)...
    劼哥stone閱讀 771評(píng)論 8 6
  • 這讓我想起了篙贸,現(xiàn)在倍受他人排擠又或者說(shuō)受到他人保護(hù)的野生稀有非主流物種:殺馬特 在木文小的時(shí)候,其實(shí)一直向往著的就...
    PTT演講閱讀 1,441評(píng)論 2 2
  • 對(duì)我們來(lái)說(shuō)敷鸦,沉迷于游戲扒披,沉迷于小說(shuō)圃泡,沉迷于刷朋友圈微博,沉迷于吃喝玩樂(lè)颇蜡,好像太容易了。這些事情都是馬上可以...
    飛花_毛毛閱讀 508評(píng)論 0 0