在這一章中,我們將大致的學(xué)習一下一些 JavaScript 中比較高級的話(huà)題,在此我們只是通過(guò)一些例子大致學(xué)習,而不進(jìn)行深入探討。
創(chuàng )建你自己的對象
正如您所看到的,JavaScript 提供了很多網(wǎng)頁(yè)組件和數據的對象及對象類(lèi)型。但是,您的目光不能僅僅限于這些,您可以根據自己的需要創(chuàng )建自己的對象、屬性和方法,這是很有用的,比如說(shuō)您需要一個(gè)比較復雜的數據結構的時(shí)候,您就需要這樣做。
在創(chuàng )建一個(gè)新的對象之前,您首先要創(chuàng )建一個(gè)數據結構。這些工作都在一個(gè)函數里邊處理,在該函數中定義您的對象的屬性(可以給這些屬性設置初始值),然后你就可以創(chuàng )建居于此對象的方法了。
【構造對象函數】
每一個(gè)對象都需要一個(gè)構造對象函數,我們通過(guò)使用 new 關(guān)鍵字調用此函數來(lái)創(chuàng )建一個(gè)新的對象實(shí)例。這類(lèi)函數定義了對象的屬性,同時(shí)給這些屬性設置初始值。您還可以在此類(lèi)函數中聲明對象的方法。
下邊就是使用構造對象函數的一個(gè)例子,在這個(gè)函數中定義了一個(gè)新的對象 Product,此對象定義了每一個(gè)產(chǎn)品的基本屬性:
function Product(name, num, price, shipping, quantity) {
this.name = name;
this.catalogNumber = num;
this.price = price;
this.shippingCost = shipping;
this.quantity = quantity;
}
var item1 = new Product("blender", "9003-2", 24.95, 2.50, 2);
var item2 = new Product("juicer", "9117-1", 49.95, 5.00, 1);
你還可以像訪(fǎng)問(wèn)其它對象的屬性那樣訪(fǎng)問(wèn) Product 對象的屬性:
var total = (item1.price + item1.shippingCost) * item1.quantity;
【定義方法】
上邊的例子中通過(guò)訪(fǎng)問(wèn) Product 對象 item1 的 price、shippingCost 和 quantity 屬性計算 item1 的總價(jià)值,如果我們需要經(jīng)常計算總價(jià)值,那么像上邊那樣用起來(lái)就很不方便,不過(guò)不用擔心,我們可以為計算總價(jià)值創(chuàng )建一個(gè)方法,很簡(jiǎn)單,只要在構造對象函數中添加一行代碼:“this.totalCost = totalCost;”,然后在構造對象函數的后邊定義一個(gè)名為 totalCost 的函數:
function Product(name, num, price, shipping, quantity) {
this.name = name; function totalCost() {
return ((this.price + this.shippingCost) * this.quantity);
this.catalogNumber = num;
this.price = price;
this.shippingCost = shipping;
this.quantity = quantity;
this.totalCost = totalCost;
}
}
var total = item1.totalCost();
如果想了解如何構建和使用自定義對象,可以看一下這個(gè) 在線(xiàn)示例 ,這個(gè)例子中定義了一個(gè)簡(jiǎn)單的購物車(chē),我們構建的對象名為 ShoppingCart,同時(shí)還給這個(gè)對象定義了增加和刪除產(chǎn)品項的方法。
Cookies
使用 cookie,您可以將一些數據信息保存在客戶(hù)端用戶(hù)的機器中,而在以后用戶(hù)瀏覽您的網(wǎng)頁(yè)的時(shí)候再調出來(lái)使用。通常我們使用 cookie 保存一些數據、登陸賬號等。
創(chuàng )建一個(gè) cookie 需要用到下邊的信息:
通常,您只需要設置前兩項 "cookie 的名字=cookie 的值" 和 "結束時(shí)間" 即可。在設置結束時(shí)間的時(shí)候,您可以使用 Date 對象,但要注意格式,單位是毫秒。下邊就是一個(gè)例子,在這個(gè)例子中,"結束時(shí)間" 被設置成從當前時(shí)間算起過(guò)任意多天 (此例設置的 "結束時(shí)間" 是 7 天后):
var days = 7;
var expdate = new Date();
expdate.setTime (expdate.getTime() + (86400 * 1000 * days));
我們通過(guò) document.cookie 屬性來(lái)對 cookie 的數據進(jìn)行存取。cookie 的格式是 "cookie的名字=cookie的值; expires=cookie的結束時(shí)間; path=路徑",而所有的 cookie 都是保存在 document.cookie 屬性中的,它們之間使用分號 ";" 分開(kāi),所以雖然您可以單獨地設置各個(gè) cookie,但卻要通過(guò)切分操作才能得到各個(gè) cookie 的值,請參照下邊的示例。
【經(jīng)常用到的 cookie 函數】
為了讓您有個(gè)好的開(kāi)始,下邊的三個(gè)函數分別提供了設置、刪除、獲取 cookie 的功能:
function setCookie (name, value, expires) {
document.cookie = name + "=" + escape(value) + function getCookie(name) {
var search;
search = name + "=" function deleteCookie(name) {
var expdate = new Date();
"; expires=" + expires.toGMTString() + "; path=/";
}
offset = document.cookie.indexOf(search)
if (offset != -1) {
offset += search.length ;
end = document.cookie.indexOf(";", offset) ;
if (end == -1)
end = document.cookie.length;
return unescape(document.cookie.substring(offset, end));
}
else
return "";
}
expdate.setTime(expdate.getTime() - (86400 * 1000 * 1));
setCookie(name, "", expdate);
}
刪除所有您不再使用的 cookie 是一個(gè)很好的習慣,因為客戶(hù)端會(huì )限制您可以存儲的 cookie 個(gè)數 (對于 Netscape 瀏覽器來(lái)說(shuō):每一個(gè)主機/域最多是 20 個(gè) cookie,總共可以存儲 300 個(gè))。上邊的刪除 cookie 的函數將 cookie 的結束時(shí)間設置成前一天的時(shí)間,這樣就可以達到刪除的目的了。
看看這個(gè) 在線(xiàn)示例 就知道上邊函數的用法了。
注意:以下的部分使用 JavaScript 1.2 ,而且只運用于 Netscape 和 IE version 4.0 或者更高版本。
事件捕捉
我們在這個(gè)教程中已經(jīng)學(xué)過(guò)了事件句柄 (event handler),Internet Explorer 瀏覽器幾乎為每一個(gè) HTML 標記提供了事件句柄,而 Netscape 卻有所不同,雖然它也為很多 HTML 標記提供了事件句柄,但是一些事件必須通過(guò)別的方法來(lái)捕捉。
【在 Netscape 中捕捉事件】
在 Netscape 4 或者更高版本的瀏覽器中,你可以捕捉當前瀏覽窗口中 window、layer 或 document 級別的對象的事件。captureEvent() 方法可以完成此操作, 此方法指定想要捕捉的事件,然后在通過(guò)編寫(xiě)函數來(lái)處理此事件句柄。
下邊的例子中我們通知 window 對象捕捉鼠標點(diǎn)擊的事件:
window.captureEvents(Event.CLICK); function myClick(even) {
window.document.onClick = myClick;
...
}
如果想捕捉更多的事件,您必須使用邏輯或運算符“|”來(lái)分割各個(gè)事件類(lèi)型,如下邊的代碼所示:
window.captureEvents(Event.MOUSEDOWN | Event.KEYDOWN);
window.document.onMouseDown = myMouseDown;
window.document.onKeyDown = myKeyDown;
我們將 event 對象傳遞給事先安排好的事件句柄 (即此事件的處理函數),這個(gè)對象包含了一些通常的時(shí)間數據,例如它的類(lèi)型等等。
【Internet Explorer 中的事件】
在 Internet Explorer 中不需要傳遞 event 對象,因為通常的時(shí)間對象都是 window 對象的一個(gè)屬性。不幸的是,IE 的這些屬性和 Netscape 的卻不盡相同。
【編寫(xiě)具有兼容性的代碼】
幸運的是,這兩種瀏覽器之間還是有共同的代碼可以使用的,最重要的是能夠使用代碼將兩種瀏覽器區分開(kāi)來(lái)。你可以嘗試使用一些對象來(lái)試探瀏覽器的類(lèi)型,例如,你可以使用 document.layers 對象來(lái)試探,這個(gè)對象是 Netscape 支持的對象,而相對應的 document.all 對象則是只有 IE 才支持的對象, Netscape 則不支持:
if (document.layers) {
// 在此處編寫(xiě) Netscape 支持的代碼 else if (document.all) {
// 在此處編寫(xiě) IE 支持的代碼 else {
// 在此處編寫(xiě) Netscape 和 IE 都支持的代碼
...
}
...
}
...
}
看一下這個(gè) 在線(xiàn)示例 將會(huì )對您又很大的幫助。例子中的代碼可以在 Netscape 和 IE 兩種瀏覽器中實(shí)現相同的效果。
正則表達式
正則表達式是用于模式匹配的,它提供了強大的字符串替換、轉換以及搜索功能。
Netscape 和 IE 在正則表達式對象的使用上有細微的不同,但是下邊的代碼卻是通用的:
var myRE = /匹配模式/標記;
匹配模式的過(guò)程被看成是逐字匹配的,同時(shí)使用正則表達式還能匹配特殊字符或特殊格式的字符串 (左邊的符號是匹配模式中使用的特殊格式):
由于 ‘*‘ 是特殊字符,它的作用是匹配零個(gè)或零個(gè)以上的 ‘*‘ 前邊的字符,所以如果想匹配字符 ‘*‘,需要在此字符前加一個(gè)反斜杠 ‘\‘ 字符。因此 ‘\*‘ 是匹配一個(gè)字符 ‘*‘。你可以到 Netscape‘s JavaScript Reference 中去看一下有關(guān)正則表達式的細節。
標記可以是下邊的值:
test() 方法用來(lái)比較已知的字符串,如果匹配則返回“真”值 (true)??梢钥匆幌逻@個(gè) 在線(xiàn)示例,在這個(gè)例子中,使用了正則表達式來(lái)判斷用戶(hù)的輸入是否符合電子郵件 (Email) 地址的格式:userid@domain.net。
動(dòng)態(tài)HTML [DHTML]
動(dòng)態(tài) HTML (Dynamic HTML 或 DHTML) 給 HTML 增加了幾個(gè)新的標記,同時(shí)也增加了幾個(gè) JavaScript 的對象。動(dòng)態(tài) HTML 的一個(gè)主要特性是充分利用網(wǎng)頁(yè)中的層 (layer) 和位置 (position)。
在這里我們再次聲明,Netscape 和 IE 在應用上是有所不同的,Netscape 增加了支持“級聯(lián)樣式單” (Cascading Style Sheets 或 CCS) 的 <LAYER> 標記用來(lái)定位網(wǎng)頁(yè)中的元素,而 IE 卻支持更多的樣式單,這些樣式單都是居于 World Wide Web 聯(lián)盟標準的 (可以參見(jiàn)第六部分的 DHTML 相關(guān)鏈接)。
【給頁(yè)面的內容定位】
雖然 Netscape 對 CSS 的支持比較有限,但是我們還是可以很容易地使用 <LAYER> 標記來(lái)創(chuàng )建被定位的內容。下邊的代碼在兩種瀏覽器中可以產(chǎn)生相同的效果:
Netscape
<layer bgcolor="#ffffcc" left=150 top=200 width=200 height=20> <div style="background-color:#ffffcc position:absolute;
顯示的文本。
</layer>
left:150px; top:200px; width:200px; height:20px;">
</div>
正如你所看到的,我們可以對被定位的內容塊 (在上邊例子中的內容塊是“顯示的文本”,也即是在 <layer>....</layer> 或 <div>....</div> 標記對之間的內容) 定義幾個(gè)特性,例如背景顏色、字體顏色等等。top 和 left 的值用來(lái)告訴瀏覽器這一塊內容在網(wǎng)頁(yè)中的位置,top 是距離瀏覽器窗口頂部的長(cháng)度,left 則是距離瀏覽器窗口左邊框架的長(cháng)度,它們的單位都是象素 (pixel)。
為了讓代碼在兩種瀏覽器中都能實(shí)現相同的效果,我們可以使用前邊講過(guò)的方法首先探測一下瀏覽器的類(lèi)型,然后再分別使用 document.writeln() 輸出適用于兩種瀏覽器的代碼參見(jiàn) 在線(xiàn)示例 。
【文檔對象模型DOM】
現在我們已經(jīng)可以給網(wǎng)頁(yè)中的內容定位了,但我們怎樣才能熟練巧妙地使用這種方法使它成為 DHTML 技術(shù)的一部分呢?“文檔對象模型” (簡(jiǎn)稱(chēng) DOM) 是一個(gè)很流行的名字,它指的是在網(wǎng)頁(yè)中的 JavaScript 分級對象。DHTML 為層與樣式單增加了一些新的對象,你可以像使用 JavaScript 中其它對象那樣使用這些對象。
當然,Netscape 和 IE 在 DOM 上的應用也有所不同,但是我們還是可以像上邊的例子那樣使用相應的代碼來(lái)實(shí)現相同的效果。
你可以將一個(gè)內容塊從一個(gè)地方移動(dòng) (重新定位) 到另一個(gè)地方,可以讓它從看得見(jiàn)變成看不見(jiàn)。為了實(shí)現這些目的,你要針對不同的瀏覽器正確地處理好 JavaScript 對象。
讓我們重新寫(xiě)一下上邊的代碼,并且在代碼中給內容塊加上名字,這樣我們才能在程序代碼中引用這些內容塊作為對象來(lái)使用 (這其實(shí)就是 DOM 的一部分):
Netscape
<layer name="block1" bgcolor="#ffffcc" left=150 top=200 width=200 height=20> <div id="block1" style="background-color:#ffffcc position:absolute;
Some text to display.
</layer>
left:150px; top:200px; width:200px; height:20px;">
Some text to display.
</div>
現在我們將內容塊放在 JavaScript 函數中當作對象來(lái)使用,同時(shí)返回此內容塊對象本身:
function getBlock(name) {
// For Netscape.
if (document.layers) // For IE.
else if (document.all) { // 以上都不是,則返回 null.
else
return(document.layers[name]);
layer = eval(‘document.all.‘ + name + ‘.style‘);
return(layer);
}
return(null);
}
現在讓我們來(lái)看一下 在線(xiàn)示例 是如何移動(dòng)一個(gè)塊的。對于 Netscape 來(lái)說(shuō),我們只要設置塊對象的 left 和 top 屬性的值就可以達到移動(dòng)塊的目的,在 IE 中則是使用 pixelLeft 和 pixelTop 屬性。在下邊的函數 moveBlockBy 中將會(huì )改變這些屬性的值:
function moveBlockBy(x, y) {
var block = getBlock("block1");
if (document.layers) {
block.left += x;
block.top += y;
}
else if (document.all) {
block.pixelLeft += x;
block.pixelTop += y;
}
}
參數 x 和 y 是塊在水平和垂直方向上的移動(dòng)增量。
【處理瀏覽器的兼容性問(wèn)題】
正如你所看到的,兩種瀏覽器在 DOM 上的運用也有很多不同之處,這樣就給你在網(wǎng)頁(yè)中實(shí)現 動(dòng)態(tài) HTML 效果帶來(lái)了挑戰,所以在編寫(xiě)代碼的時(shí)候應該盡量避免使用不兼容的屬性、方法等。
當然,你也可以只設計謀一種瀏覽器的代碼,例如只設計 IE 瀏覽器可執行的代碼,而不考慮 Netscape,但是這樣你就將會(huì )失去 Netscape 的用戶(hù)群?;蛘吣阋部梢栽O計多套網(wǎng)頁(yè)或網(wǎng)站,讓它們分別支持各種瀏覽器,但是這樣將會(huì )給維護網(wǎng)頁(yè)或網(wǎng)站帶來(lái)很大的麻煩,增加復雜性。
聯(lián)系客服