《JavaScript Dom編程藝術》讀書筆記(五)

函數

若是須要屢次使用同一段代碼,能夠把它們封裝成一個函數。函數就是一組容許在你的代碼裏隨時調用的語句。事實上,每一個函數實際是一個短小的腳本。html

先對函數作出定義再調用是一個良好的編程習慣。下面是一個簡單的示例函數:node

function shout() {
    var beatles = Array("John","Paul","George","Ringo");
    for (var count = 0; count < beatles.length; count++ ) {
        alert(beatles[count]);
    }
}

這個函數裏的循環語句將依次彈出對話框來顯示Beatles樂隊成員的名字。若是想在本身的腳本里執行這一動做,能夠隨時使用以下的語句來調用這個函數:程序員

shout();

每當須要反覆作一件事,均可以利用函數來避免重複鍵入大量的相同內容。能夠將不一樣的數據傳遞給它們,而它們將使用這些數據去完成預約的操做。傳遞給函數的數據稱爲參數(argument)。編程

定義一個函數的語法:數組

function name(arguments) {
    statements;
}

JavaScript提供了許多內建函數,在前面屢次出現過的alert就是一例。這個函數須要咱們提供一個參數,它將彈出一個對話框來顯示這個參數的值。瀏覽器

在定義函數時,能夠爲它聲明任意多個參數,只要用逗號把它們分隔開來就行。在函數額內部,你能夠像使用普通變量那樣使用它的任何一個參數。安全

下面是一個須要傳遞兩個參數的函數。若是把兩個數值傳遞給這個函數,這個函數將對它們進行乘法運算:函數

function multiply(num1,num2) {
    vartotal = num1 * num2;
    alert(total);        
}

在定義了這個函數的腳本里,咱們能夠從任意位置去調用這個函數,以下所示:this

multiply(10,2);

屏幕上會馬上彈出一個顯示乘法運算結果(20)的alert對話框。函數不只可以(以參數的形式)接收數據,還可以返回數據。code

能夠建立一個函數並讓它返回一個數值、一個字符串、一個數組或一個布爾值。這須要用到return語句:

function multiply(num1,num2) {
    var total = num1 * num2;
    return total;
}

下面這個函數只有一個參數(一個華氏溫度值),它將返回一個數值(同一溫度的攝氏溫度值):

function converToCelsius(temp) {
    var result = temp - 32;
    result = result / 1.8;
    return result;
}

還能夠把函數當作一種數據類型來使用,這意味着能夠把一個函數的調用結果賦給一個變量:

var temo_fahrenheit = 95;
var temp_celsius = convertToCelsius(temp_fahrenheit);
alert(temp_celsius);

把華氏溫度值95轉換爲攝氏溫度值。這個例子中,變量temp_celsius的值將是35,這個數值由convertToCelsius函數返回。

變量的做用域

好比下面這個例子:

function square(num) {
    total = num * num;
    return total;
}
var total = 50;
var number = square(20);
alert(total);

全局變量total的值變成了400。本意是讓square()函數只把它計算出來的平方值返回給變量number,但由於未把這個函數內部的total變量明確地聲明爲局部變量,這個函數把名字一樣是total的那個全局變量的值也改變了。

把這個函數寫成以下所示的樣子纔是正確的:

function square(num) {
    var total = num * num;
    return total;
}

如今,全局變量total變得安全了,再怎麼調用square()函數也不會影響到它、

請記住,函數在行爲方面應該像一個自給自足的腳本,在定義一個函數式,必定要把它內部的變量所有明確地聲明爲局部變量。若是你老是在函數裏使用var關鍵字來定義變量,就能避免任何形式的二定義隱患。

獲取元素

有3種DOM方法可獲取元素節點,分別是經過元素ID、經過標籤名字和經過類名字來獲取。

getElementById

DOM提供了一個名爲getElementById的方法,這個方法將返回一個與那個有着給定id屬性值的元素節點對應的對象。

它是document對象特有的函數。在腳本代碼裏,函數名的後面必須跟有一對圓括號,這對圓括號包含着函數的參數。getElementById方法只有一個參數:你想得到的那個元素的id屬性的值,這個id值必須防止單引號或雙引號裏。

document.getElementById(id)

下面是一個例子:

document.getElementById("purchases")

這個調用將返回一個對象,這個對象對應着document對象裏的一個獨一無二的元素,那個元素的HTMLid屬性值是purchases。你能夠用typeof操做符來驗證這一點。typeof操做符能夠告訴咱們它的操做數是一個字符串、數值、函數、布爾值仍是對象,例如:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Shopping list</title>
</head>
<body>
    <h1>What to buy</h1>
    <p title="a gentle reminder">Don't forget to buy this stuff.</p>
    <ul id="purchases">
        <li>A tin of beans</li>
        <li class="sale">Cheese</li>
        <li class="sale important">Milk</li>
    </ul>
    <script>
        alert(typeof document.getElementById("purchases"))
    </script>
</body>
</html>

在瀏覽器中加載這個例子時,會彈出一個alert對話框,報告document.getElementById("purchases")的類型————它是一個對象。

事實上,文檔中的每個元素都是一個對象。利用DOM提供的方法可以獲得任何一個對象。

getElementsByTagName

getElementsByTagName方法返回一個對象數組,每一個對象分別對應着文檔裏有着給定標籤的一個元素。相似於getElementById,這個方法也是隻有一個參數的函數,它的參數是標籤的名字:

element.getElementsByTagName(tag)

它與getElementById方法有許多類似之處,但它返回的是一個數組。下面是一個例子:

document.getElementsByTagName("li")

這個調用將返回一個對象數組,每一個對象分別對應着document對象中的一個列表項元素。與任何其餘的數組同樣,咱們能夠利用length屬性查出這個數組裏的元素個數。

在以前的例子中將<script>標籤中的alert語句替換爲下面這條語句:

alert(document.getElementsByTagName("li").length);

能夠看到這份示例文檔裏的列表項元素的個數:3.這個數組裏的每一個uyansu都是一個對象。能夠經過利用一個循環語句和typeof操做符去遍歷這個數組來驗證這一點。例如,下面這個for循環:

for(var i=0; i < document.getElementsByTagName("li").length; i++ ) {
alert(typeof document.getElementsByTagName("li")[i]);
}

特別要注意的是,即便在整個文檔裏這個標籤只有一個元素,getElementsByTagName也返回一個數組,數組的長度爲1。

用鍵盤反覆敲入 document.getElementsByTagName("li")是件很麻煩的事情,而這些長長的字符串會讓代碼變得愈來愈難以閱讀。有個簡單的辦法能夠減小沒必要要的打字量並改善代碼的可讀性:只要把 document.getElementsByTagName("li")賦值給一個變量便可。

var items = document.getElementsByTagName("li");
for (var i=0; i < items.length; i++) {
    alert(typeof items[i]);
}

如今能夠看到alert對話框,顯示的消息都是「object」。

getElementsByTagName容許把一個通配符做爲它的參數,意味着文檔裏的每一個元素都將在這個函數所返回的數組裏佔有一席之地。通配符(星號字符「*」)必須放在引號裏,是爲了讓通配符與乘法操做符有所區別。若是想知道某份文檔裏總共有多少個元素節點,像下面這樣使用通配符便可:

alert(ducoment.getElementsByTagName("*").length);

還能夠把getElementById和getElementByTagName結合起來運用。例如,以前的幾個例子都是經過document對象調用getElementByTagName的,若是隻想知道id屬性值是purchase的元素包含着多少個列表項,必須經過一個更具體的對象去調用這個方法,以下所示:

var shopping = document.getElementById("purchases");
var items = shopping.getElementsByTagName("*");

這兩條語句執行完畢後,items數組將只包含id屬性值是purchase的無序清單裏的元素。具體到這個例子,items數組的長度恰好與這份文檔裏的列表項元素的總數相等:

alert (items.length);

若是還須要更多的證據,下面這些語句將證實items數組裏的每一個值確實是一個對象:

for(var i=0; i < items.length; i++) {
    alert(typeof items[i]);
}

getElementsByClassName

getELementsByClassName這個方法讓咱們可以經過class屬性中的類名來訪問元素。與getElementsByTagName方法相似,getElementByClassName也只接受一個參數,就是類名:

getElementsByClassName(class)

這個方法的返回值也與getElementsByTagName相似,都是一個具備相同類名的元素的數組。下面這行代碼返回的就是一個數組,其中包含類名爲「sale」的全部元素:

document.getElementsByClassName("sale")

使用這個方法還能夠查找哪些帶有多個類名的元素。要指定多個類名,只須要在字符串參數中用個空格分隔類名便可。例如,在<script>標籤中添加下面這行alert代碼:

alert(document.getElementsBuClassName("important sale").length);

彈出框顯示1,表示只有一個元素匹配,由於只有一個元素同時帶有「important」和「sale」類名。即便在元素的class屬性中,類名的順序是「sale import」而非參數中指定的「import sale」也照樣會匹配該元素。不只類名的實際順序不重要,就算元素還帶有更多類名也沒有關係。

與使用getElementsByTagName同樣,也能夠組合使用getElementsByClassName和getElementById。若是想知道在id爲「purchases」的元素中有多深類名包含「sale」列表項,能夠先找到那個特定的對象,而後再調用getElementsByClassName:

var shopping = document.getElementById(「purchases」);
var sales = shopping.getElementsByClassName("sale");

這樣,sales數組中包含的就只是位於「purchases」列表中的帶有「sale」類的元素。運行下面這行代碼,就會看到sales數組中包含兩項:

alert(sales.length);

這個getElementsByTagName的方法很是有用,但只有較新的瀏覽器才支持它。爲了彌補這一不足,DOM腳本程序員須要使用已有的DOM方法來實現本身的getElementsByClassName。而多數狀況下,他們的實現過程都與下面這個getElementsByClassName大體類似,這個函數能適用於新老瀏覽器:

function getElementsByClassName(node, classname) {
    if (node.getElementsByClassName) {
        //使用現有方法
        return node.getElementsByClassName(classname);
    } else {
        var results = new Array();
        var elems = node.getElementsByTagName("*");
        for (elems[i].className.indexOf(classname)!= -1){
            results[results.length] = elems[i];
        }
    }
    return results;
}

這個getElementsByClassName函數接受兩個參數。第一個node表示DOM樹中的搜索起點,第二個classname就是要搜索的類名了。若是傳入節點上已經存在了適當的getElementsByClassName函數,那麼這個新函數就直接返回相應的節點列表。若是getElementsByClassName函數不存在,這個新函數就循環遍歷全部標籤,查找帶有相應類名的元素(不適用於多個類名)。若是使用這個函數來模擬前面取得購物列表的操做,能夠以下寫:

var shopping = document.getElementById("purchases");
var sales = getElementsByClassName(shopping, "sale");
相關文章
相關標籤/搜索