Head First JavaScript 之 DOM

【問題】If some one handed me 一個對象,那我有沒有得到這個對象中包含的所有的屬性辦法?
【回答】

/* 使用for in來遍歷得到對象的屬性*/

for (var i in car) {
var car = {
};

===================================

不知不覺,我學習《Head First JavaScript》已經來到了DOM這個章節了,雖然在上課的時候,這些已經講過了,但我在課堂上對這些知識的理解仍不夠OK,所以,希望,新的一章能夠帶給我驚喜吧!

大二第一學期開學之前,我就開始接觸了這本書,可以說是這本書帶著我入門的,沒有它帶我入門的話,估計在新學期所要學的JavaScript我會有可能因為是新知識,新挑戰而無法輕易接受,更有可能影響一整個學期的心情。幸好,有了這本書,幸好在開學前我接觸到了這本書。

這段時間也讓我懂得了一些道理,凡事就應該要有備而無患。

下面是我對新章節的筆記:

"DOM"這個初聽起來,感覺很高端的樣子。我之前在一本叫做《瘋狂的程序員》的書中便看到這個詞,我以為這是他們行業中某個領域的專有的名詞,高大上到我只能仰望。但其實不是這樣的。

"DOM"的全稱是 Document Object Model. 光從字面上理解起來,就可以發現,我們也隨著這個"高大上"的詞高大上起來了。

我們知道,HTML是標記語言,一般是靜態的頁面,而JavaScript是程序設計語言,可以寫出有順序先后,邏輯性強等等的代碼,JS(為了方便一點,以下所有的"JavaScript"我都稱為JS,貌似本來就可以這么稱呼的...)與HTML結合使用,還可以使頁面更好地用戶交互的,從而使得靜態頁面上升到動態的頁面。在HTML文件中嵌入script標簽可以建立起HTML與JS之間的聯系,但是,他們之間是以什么方式來進行溝通的呢?在書中說是通過DOM來代表我們的HTML頁面,轉而以DOM向JS互聯溝通。
那DOM是如何出現的呢?為了熟悉這個看似高大上的名詞,我們【書本和我還有感興趣的你們】進行了一下探討:

  1. 當你的瀏覽器加載一個HTML頁面時,瀏覽器在解析HTML標簽語句的同時,還會顯示在瀏覽器的窗口中。但是更接近DOM的一方面,瀏覽器還會創建了一些列能夠代表我們的HTML標簽的對象,這些對象就存放在了DOM里面。
    html
    |
    -----------------------
    | |
    head body
    | |
    ----------- -----------------
    | | | | |
    title script h1 h2 p
    ...........

    1. 當頁面加載完成后,相應地,瀏覽器也產生了一系列與頁面標簽對應的對象元素,這些對象元素存放在DOM(Document Object Model)中,于是,JS通過訪問DOM中的對象元素就可以獲取到該對象所代表的html標簽,比如:
      HTML頁面中有一個段落<p>
      <p>Hello! JS!</p>
      
      假設現在上面的html已被瀏覽器加載完成,那么就存在一個與上面的<p>標簽對應的對象元素,這個元素屬于DOM模型中的一員,JS可以通過訪問這個對象來訪問<p>標簽,從中,也可以得到段落<p>里面的內容"Hello! JS!"
      
      JS如何獲取到DOM中已存在的對象元素呢?
      后面會繼續提到。。
      
    2. JS通過DOM獲取到了元素,便可以對元素本身所包含的信息進行查看,或者設置。更厲害的,JS讓DOM創建元素,刪除元素。怎么回事呢?簡單說明一下:
    DOM創建元素:增加與新添元素對應的html標記到html頁面中。
    DOM刪除元素:刪除掉html文件中對應的標簽。
    
    如何做到的呢?
    后面就會提到了。。。
    

探討結束!JS通過訪問DOM中的元素來得到html文件中類似"p","h1"<span>,<input>,<div>.<table>等等之類的標簽的訪問。從中對標簽進行查看以及修改。
于是,他們之間的溝通就是這樣在進行著...

==============================

上面我總是說"JS通過DOM可以獲取到什么什么",是否依然感到疑惑,DOM這個詞倒是接觸得多了,可具體什么含義呢?
"獲取"又是如何做到的呢?

下面做一點個人理解補充:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>My blog</title>
    <script src="blog.js"></script>
  </head>
<body>
    <h1>My blog</h1>
    <div id="entry1">
        <h2>Great day bird watching</h2>
        <p id = "para">
        Today I saw three ducks!
        I named them
        Huey, Louie, and Dewey.
        </p>
        <p>
        I took a couple of photos...
        </p>
    </div>
</body>
</html> 

瀏覽器通過加載上面的html代碼之后就會產生一個完整的頁面了。

在JavaScript中有一個內置對象是 document。
這個內置對象document就相當于是瀏覽器所加載完成的頁面,也相當于document對象擁有這個對象的DOM樹(如果不理解DOM樹可以參考個人畫的DOM樹圖,也可以自行百度更多詳細信息)。

JS訪問到DOM中的節點是如何做到?
答:JS使用的內置對象document中的getElementById方法,參數是節點的id。如上HTML代碼中的id 為 "entry1"的div標簽,JS要想獲取這個標簽,可以這么做:

document.getElementById("entry1");
提示,document對象有一系列,很多的getElement方法可以獲取到DOM樹中的節點元素,對應HTML頁面的各個標簽。比如<div><p><ul><li><img>等等等等.

JS獲取到了頁面文檔的節點元素之后,我們可以通過JS代碼來實現出許多有趣的功能。

【案例一】更改段落節點的內容

描述:我們有一個HTML文檔,<body>標簽中僅有一個<p>標簽,<p>標簽里面的內容為"HelloWorld!"
我們的目的是將<p>標簽的文本內容"HelloWorld!"替換為"HelloJs!"
怎么實現呢?

<html>
    <head>
    <title>Update the content of element</title>
        <script src = "exp_1.js" type = "text/JavaScript"></script>
    </head>
    <body>      
        <p id = "target">HelloWorld!</p>
    </body>
</html>

上面給出了HTML代碼部分:用瀏覽器打開這個html文件,能看到的只是<p>標簽帶來的HelloWorld!

下面,我們使用JS代碼來改變這個<p>標簽的內容:

// window.onload = function () {};  這個的作用是等待頁面加載完成了之后,執行該匿名函數

window.onload = function () {
    var ele = document.getElementById("target");  // 獲取到DOM中id為target的元素,即對應頁面文檔中的<p>標簽
    ele.innerHTML = "HelloJs!"
    // OK! END~
};

上面的JS代碼實現了修改<p>標簽的內容這個小功能。
步驟:

  1. document對象獲取了一個指向DOM中id = "target"元素(<p>標簽)的引用。并將這個引用賦值給變量ele.(意味著ele也可以操作這個id = target的元素)
  2. 使用元素的屬性innerHTML對DOM中id = "target"的元素進行內容的更改,這一點點改動,會直接影響到瀏覽器中的頁面,使得瀏覽器中的頁面也發生了變動。即“HelloWorld!”變為"HelloJs!"

Q:當我使用document的getElementById方法時,傳入了一個不存在的id,會出現什么結果?
A:我們知道,getElementById方法會找到DOM中id與該方法所得到的參數相同的元素,并返回。那如果這個ID本身是不存在的,那么,這個方法將返回null。

從這本書中,我知道了getElement系列方法的getELementsByClassName()的方法,這個方法將會返回一個集合。

Q:一個我比較模糊的概念,element object元素對象(DOM中)到底是什么?
A:這個問題也是最近一直困擾著我。

we're just assigning the function value to the window.onload property.

一個問題,我們寫的JS代碼是放在<head>標簽中的,而<head>標簽又是比<body>標簽還要快執行的,就是說在JS執行document.getELementByID("xxx")的時候,頁面<body>標簽中的代碼一句都未被執行,則頁面并沒有完全加載完成,也就是說DOM樹結構也并未建立起來。DOM中不存在id = “xxx”的元素對象。
那怎么辦呢?眼睜睜地看著瀏覽器報錯嗎?我明明在<body>里面有id = "xxx"的那個標簽呀!

莫著急,下面我們來解決問題,上面是說瀏覽器會先執行位于<body>前面的<head>對不對,那么,在執行head中的<script>標簽里的代碼時,網頁還沒有完全加載出來,此時DOM結構還是不完整的。所以無論在JS如何去查找那個id = "xxx" 的元素,也是白費功夫,因為DOM還未建立,id = "xxx"的元素對象也就無法出現在DOM中。導致查找語句最終總是返回null.

怎么來解決這個問題呢?
答案是,我們需要告訴瀏覽器說,我要等你將整個頁面執行完了之后再來執行我的代碼 document.getElementByID("xxx");
好,瀏覽器這時就對我們說了:“那這好辦啊,你可以將你那些需要在頁面加載完畢后在執行的代碼封裝在一個函數中,然后將這個函數復制給我的onload屬性就好了。”
操作如下:

function init () {
    document.getElementByID("xxx");
}
window.onload = init;

任何一個DOM元素都有一個setAttribute方法

每一個DOM元素都會有自己的各個屬性以及對應的屬性值,一般在HTML頁面中比如一個<p>標簽可以有id屬性,可以有class屬性,align屬性等等,可以在HTML頁面代碼中直接指定其屬性值。在JS代碼中想要為其中某個屬性賦值,可以使用setAttribute()方法。
使用方法如下:
元素.setAttribute("屬性名", "屬性值");
例子:
```JavaScript
<html>
  <head>
    <meta charset = 'utf-8'>
    <title>...</title>
    <!-- CSS部分 -->
    <style>
        .eg {
            color:red;
        }
      </style>
      <script>
        window.onload = function () {
            var p = doucment.getElementByID("pp");
            p.setAttribute("class", "eg");
        }
        </scirpt>
    </head>
    <body>  
      <p id = "pp">我是一個段落,我是被JS代碼修改屬性“class”的值后,才會變成紅色的。</p>
      </body>
  </html>
```

想知道元素中某個屬性的值?
沒問題,我們有另外一個方法 getAttribute:

元素.getAttribute("元素的屬性名");

假如元素中不存在我們要查找的屬性名,則執行getAttribute方法

不知不覺,我就把這一章節————DOM編程看過去了,將要進入新的章節。


【問題】如何檢驗一個變量(或者是數組元素,對象屬性)是否未實例化呢?
【回答】
```JavaScript
var i;  // 這里定義了一個未實例化的變量i,此時i沒有實際的值,所以其類型為undefined

if (i == undefined) {
    // i isn't defined! just deal with it.
}

要注意undefined與"undefined"之間是由著天大的差別的。

在JavaScript中使用NaN -- not a number 來表示一個不可計算,不可描述的數值類型。如 0 / 0 的結果計算出來本身就是一個錯誤的不可計算的結果,所以0/0的結果在JavaScript中等于NaN.

但奇怪的是,如果那NaN與NaN去比較,會得出這樣的一個結果:
NaN != NaN;

isNaN(xx)

如果xx參數的值不是一個數字,那么isNaN()方法會返回真。

進入下一個筆記點
觀察下面的代碼,你認為會輸出那個:

if (99 == "99") {
console.log("A number equals a string!");
} else {
console.log("No way a number equals a string");
}

太天真了,我以為肯定會執行else分支的,畢竟數字怎么可能等于一個字符串嘛.
原來,JavaScript與其他的編程語言不同,JavaScript可以在連個不同類型的變量進行比較(compare)時,會自動將一個變量類型轉換為與之比較的類型的變量。

Case1 數值型變量與字符型變量之間的比較

if (99 == "99") {
return true;
}

上面的小段程序是成立的。JavaScript會自動將字符串"99"轉換為數值型99,,然后再進行比較,此時兩個數值類型99當然相等了,那么就各異返回真了。

Case2 數值型變量與布爾型變量比較的情況:

1 == true; // 左邊為數值型,右邊為true,布爾型

// JavaScript自動將布爾類型 true/false 分別轉換成為 1/0. 所以 1 == true 也就相當于:
1 == 1; // 該表達式成立即1 == true 成立。

Case3 字符串類型變量與布爾類型變量一起比較

"1" == true; // ???


首先JavaScript會自動將true轉換為1,得到 "1" = 1;
此時一邊為字符串類型的"1",而另一邊則是數值類型的1,那么JavaScript會把字符串類型"1" 變為 數值類型1,得到
1 = 1; // 表達式兩邊的變量類型是相等的,所以該表達式可以返回true.

=== 的作用:

在比較表達式兩邊變量類型相同、值相同之后,會返回true.

=============
console.log(1.2 == "1.2");
VM1962:1 true
=============

=============
console.log("true" == true);
VM1987:1 false

JS 將 true 轉換為1,得到
"true" == 1; // ???
Js將字符串"true"轉換為數字,但是轉換失敗得到NaN
所以,
NaN == 1; // false
所以"true" == true,該表達式無法成立。
=============

=============
雖然說JavaScrit有這種操作符"===",但是JavaScript不存在類似的 <== 或者 >== 等操作符。
不過 === 相對應的是 !==

=== 的作用是檢查等式兩邊的變量是受類型相同且值相等。
!== 的作用與 === 相反。
=============

=============
console.log("1" < "2");
VM2012:1 true
undefined
console.log("1" > "2");
VM2013:1 false
undefined
=============
console.log("mango" > "banana");
VM2038:1 true
字符串之間的大小比較是通過其首字母來比較的,那么我又下列疑問:
"m1" < "m2" ???
動手嘗試一次:
console.log("m1" < "m2");
VM2070:1 true
=============

11月份的到此結束了,11月我在黨組織的領導下,觀看視頻,接受培訓課程,參觀紅色基地,寫了不少材料。這個月過得,有意義但卻容易失去。我做總結的習慣仍然沒有完全養成。。。今天是校運動會,我與社團的其他同學一起去參加錄入運動員成績的工作,雖然做的事情有時候會單調,可不知道為什么,我卻感受到其中的一些意義,光學會專業并不會是一艘直達終點的小船,有時為了能更快,更省力到達終點,我們要學會使用工具,船槳,路線圖等等。我們需要其他方面的豐富的知識來做輔助,才有可能做到心中所想。

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

推薦閱讀更多精彩內容

  • 問答題47 /72 常見瀏覽器兼容性問題與解決方案? 參考答案 (1)瀏覽器兼容問題一:不同瀏覽器的標簽默認的外補...
    _Yfling閱讀 13,814評論 1 92
  • 之前通過深入學習DOM的相關知識,看了慕課網DOM探索之基礎詳解篇這個視頻(在最近看第三遍的時候,準備記錄一點東西...
    微醺歲月閱讀 4,533評論 2 61
  • 在線閱讀 http://interview.poetries.top[http://interview.poetr...
    前端進階之旅閱讀 114,841評論 24 450
  • 一、JS前言 (1)認識JS 也許你已經了解HTML標記(也稱為結構),知道了CSS樣式(也稱為表示),會使用HT...
    凜0_0閱讀 2,807評論 0 8
  • 彈指一揮間,已經忘記一起走過了多少個年月。 我們最終還是無法阻擋時間匆匆的步伐。 那年那...
    漆夜微涼閱讀 524評論 0 2