在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ HTML/ 客戶端的 JavaScript
面向?qū)ο蟮?Javascript
客戶端的 JavaScript
概述
核心概念深入
函數(shù)式的 Javascript
對象與 JSON
前端 JavaScript 框架
基本概念
數(shù)組
閉包
正則表達(dá)式
函數(shù)

客戶端的 JavaScript

毫無疑問,到目前為止,JavaScript應(yīng)用最為廣泛,也最為成功的領(lǐng)域就是客戶端,或者稱為瀏覽器上的JavaScript。JavaScript為頁面開發(fā)注入了活力,如與服務(wù)器交互形成的局部刷新,鼠標(biāo)事件的響應(yīng),動態(tài)的頁面風(fēng)格變換等等,都直接依靠與JavaScript的支持。

客戶端 JavaScript 執(zhí)行環(huán)境

我們在基礎(chǔ)部分提到過,JavaScript代碼都有一個執(zhí)行環(huán)境,所有的JavaScript代碼均被包含在一個全局對象中,比如在所有函數(shù)之外聲明:

var x = 3;  
var str = "global";  

這兩個變量聲明語句事實(shí)上是為全局對象添加了兩個屬性x和str??梢詫⑷謱ο笙胂蟪梢粋€大的匿名自執(zhí)行函數(shù):

<span style="font-family: 'Courier New'; font-size: x-small;">(function(){  
    var x = 3;  
    var str = "global";  
    //...  
})();</span>  

在瀏覽器端,這個全局的對象稱為window,window是所有JavaScript對象的根,我們可以通過window對象的屬性document來訪問頁面本身,也可以調(diào)用window的一些方法來與用戶交互,比如:

window.alert("This is a message");  
alert("This is a message");  

這兩個語句事實(shí)上的效果是相同的,在引用全局對象window的方法時,我們可以忽略前綴,只使用方法名本身。

window對象是對瀏覽器當(dāng)前窗口的引用,因?yàn)闉g覽器會將window與自身繪制出來的窗口綁定起來,我們對window的操作事實(shí)上會映射到瀏覽器窗口上。正是瀏覽器本身提供了這種腳本化的能力,我們才有機(jī)會通過JavaScript代碼來完成諸如改變頁面標(biāo)題,彈出警告框,修改頁面內(nèi)容(通過對window.document的修改)等操作。

文檔對象模型(DOM)

DOM即文檔對象模型,它是一個平臺,提供語言無關(guān)的API,允許程序訪問并更改文檔的內(nèi)容,結(jié)構(gòu)以及樣式。HTML文檔是一個樹形的結(jié)構(gòu),與瀏覽器中的頁面中的結(jié)構(gòu)一一對應(yīng)。

http://wiki.jikexueyuan.com/project/javascript-core/images/jsc.gif" alt="" />

圖 W3C站點(diǎn)中的一個HTML結(jié)構(gòu)示例

JavaScript通過修改/遍歷DOM,即可映射到對WEB頁面的操作上,比如一個簡單的頁面如下:

<html>  
    <head>  
    </head>  
    <body>  
       <div id="con">  
       </div>  
    </body>  
</html>  

通過JavaScript操作DOM:

var con = document.getElementById("con");  

即可對應(yīng)到WEB頁面中的id為”con”的div標(biāo)簽,可以為該標(biāo)簽設(shè)置背景色,或者綁定click事件的處理函數(shù)等等。JavaScript可以通過一些瀏覽器內(nèi)置的方法來對DOM進(jìn)行遍歷,增加,刪除DOM的子節(jié)點(diǎn),訪問DOM上的Form,F(xiàn)rame,Image等節(jié)點(diǎn),修改他們的CSS樣式,注冊/注銷事件處理函數(shù),從而使頁面“活動”起來。

事件驅(qū)動模型

由于客戶端JavaScript的開發(fā)屬于用戶界面開發(fā)的范疇,因此使用事件驅(qū)動模型就顯得非常自然了,事件驅(qū)動的特點(diǎn)在于:代碼塊的運(yùn)行與否與程序流程無關(guān)。而傳統(tǒng)的流式代碼的特點(diǎn)是,從函數(shù)的入口進(jìn)入,依次調(diào)用各個子模塊的處理函數(shù),最后退出。這種編程模式主要適用于與UI關(guān)系不大的場合,很少有異步的過程,這些特點(diǎn)可能要追溯到計算機(jī)程序的最初模型:批處理。

而 事件驅(qū)動模型主要是面向用戶的,你在實(shí)現(xiàn)無法知道用戶會如何使用你的程序,因此就只能通過回調(diào),事件監(jiān)聽等方式,當(dāng)用戶做出某個動作時才會觸發(fā)之前已經(jīng)注 冊好的監(jiān)聽器,從而執(zhí)行相關(guān)代碼,而不是順序的執(zhí)行。甚至在一次運(yùn)行中,部分代碼始終沒有被觸發(fā),也就根本不會被執(zhí)行到。

比如在頁面中,我們?yōu)榘粹o的點(diǎn)擊事件注冊了事件監(jiān)聽器,當(dāng)點(diǎn)擊的時候彈出一個對話框,但是用戶打開頁面后,瀏覽完內(nèi)容后就直接關(guān)閉了,沒有點(diǎn)擊按鈕,那么相關(guān)的代碼就沒有被觸發(fā),我們來看一個簡單的示例:

我們有一個頁面,內(nèi)容如下:

<html>  
<head>  
<style>  
body{  
    margin: 20px;  
    font-family : "Verdana";  
    font-size : normal;  
    background-color : #eee;  
}  
</style>  
</head>  
<body onload="init()">  
    <p>  
        <label for="toclick">Please click the button:</label>  
        <input id="toclick" type="button" value="Click me" />  
    </p>  
</body>  
</html>  

http://wiki.jikexueyuan.com/project/javascript-core/images/jsc1.png" alt="" />

圖 頁面click-me的展示

可以看到body標(biāo)簽的onload屬性被賦予一個值”init()”,這是一個對JavaScript代碼的調(diào)用,時機(jī)發(fā)生在當(dāng)頁面加載完成之后,也就是瀏覽器已經(jīng)創(chuàng)建了所有body中的DOM對象之后。

我們來看看這個init函數(shù)的內(nèi)容:

<script type="text/javascript" language="javascript">  
function init(){  
    var button = document.getElementById('toclick');  
    button.onclick = function(){  
        alert('button is clicked');  
    }  
}  
</script>  

這段代碼先從document中獲取id為”toclick”的元素(也就是我們剛才在html中聲明的button),然后為其click事件綁定一個函數(shù),當(dāng)click事件被觸發(fā)時,彈出一個警告框。

http://wiki.jikexueyuan.com/project/javascript-core/images/jsc2.png" alt="" />

與服務(wù)器端交互(Ajax)

Ajax本身被作為前端技術(shù),提出的時間是比較早的,但是由于種種原因,沒有引起人們的普遍關(guān)注,而當(dāng)Google的很多產(chǎn)品如Google Map,GMail等橫空出世的之后,Ajax才被越來越多的公司所接受并引入到自己的產(chǎn)品中。現(xiàn)在幾乎所有的網(wǎng)站都有不同層次的Ajax交互,純靜態(tài)的頁面已經(jīng)非常少了。

簡而言之,Ajax表示異步JavaScript與XML,事實(shí)上,Ajax與XML幾乎沒有任何關(guān)系,因?yàn)槭钱惒浇换?,所以用戶的頁面不用刷新,在同一個頁面中,客戶端請求服務(wù)數(shù)據(jù),當(dāng)服務(wù)數(shù)據(jù)返回時,通過JavaScript將數(shù)據(jù)片段填充到頁面的某個部分,即實(shí)現(xiàn)了局部刷新,這個過程對用戶來說實(shí)際上是透明的。

Ajax對服務(wù)器端沒有限制,一個Ajax請求和普通的請求一樣,發(fā)送數(shù)據(jù)(GET/POST)到一個服務(wù)端URL上。服務(wù)端的實(shí)現(xiàn)可以是php,可以是ASP或者JSP等。以J2EE為例,數(shù)據(jù)發(fā)送到servlet,servlet對請求進(jìn)行處理,最后向輸出流寫入數(shù)據(jù),瀏覽器得到這些數(shù)據(jù)之后,會按照Ajax調(diào)用時的注冊情況來回調(diào)JavaScript函數(shù),JavaScript在操作DOM上具有天生的優(yōu)勢,因此可以很方便的在無刷新的情況下更新頁面的部分或者全部。

下面我們來看一個具體的實(shí)例,通過異步的向后端的php腳本發(fā)送請求,頁面的內(nèi)容得到了局部更新,而無需重刷整個頁面。首先編寫一個簡單的php腳本:

<?php  

$type = $_REQUEST['type'];  
$string = $_REQUEST['string'];  

if($type == 0){  
    echo strtoupper($string);  
}else{  
    echo strtolower($string);  
}  

?>  

php的邏輯很簡單,請求中包含兩個參數(shù),type和string,如果type為0,則將第二個參數(shù)string轉(zhuǎn)換為大寫返回,否則轉(zhuǎn)換為小寫返回。

XMLHttpRequest對象是進(jìn)行Ajax的核心,所有的主流瀏覽器都已各自不同的方式進(jìn)行了實(shí)現(xiàn),如果不使用客戶端JavaScript框架,那么使用起來會有所差異:

function initxhr(){  
    if(window.XMLHttpRequest){  
        xhr = new XMLHttpRequest();  
    }else if(window.ActionXObject){  
        xhr = new ActiveXObject("Msxml2.XMLHTTP");  
    }else{  
        throw new Error("xhr is not supported");  
    }  
}  

創(chuàng)建了XMLHttpRequest對象之后,我們即可使用它來進(jìn)行與服務(wù)端的異步通信:

function doajax(url, panelId){  
    if(xhr == null){  
        initxhr();  
    }  

    if(xhr != null){  
        xhr.open("GET", url, true);  
        xhr.onreadystatechange = updatePanel(panelId);  
        xhr.send(null);  
    }else{  
        throw new Error("xhr is not inited");  
    }  
}  

通過設(shè)置XMLHttpRequest對象的onreadystatechange屬性,當(dāng)服務(wù)端產(chǎn)生響應(yīng)時,瀏覽器會回調(diào)此處注冊的函數(shù):

function updatePanel(panelId){  
    return function(){  
        if(xhr.readyState == 4){  
            var response = xhr.responseText;  
            alert(response);  
            document.getElementById(panelId).innerHTML = response;  
        }  
    }  
}  

運(yùn)行結(jié)果如下:

http://wiki.jikexueyuan.com/project/javascript-core/images/jsc3.png" alt="" />

調(diào)試

在實(shí)際的開發(fā)環(huán)境中,不可能做到代碼沒有bug,變量的拼寫錯誤,使用了未經(jīng)初始化的變量,死循環(huán)等等,這些都是比較容易解決的錯誤,但是如果有隱藏的比較深的bug,時隱時現(xiàn),我們就需要一個調(diào)試環(huán)境了。腳本語言的調(diào)試尤其艱難,因?yàn)橐磺卸际沁\(yùn)行時決定的,因此不可能預(yù)先知道代碼有錯誤(不包括顯式的詞法錯誤)。

我們這一節(jié)中介紹集中瀏覽器中的調(diào)試JavaScript的方式。

FireFox

FireFox以速度,可擴(kuò)展性,標(biāo)準(zhǔn)性深受廣大開發(fā)人員的喜愛。FireFox具有強(qiáng)大的插件機(jī)制,用戶可以自己為FireFox增添新的功能(很多插件只需要有JavaScript/CSS/XUL經(jīng)驗(yàn)即可),而WEB開發(fā)人員最喜愛的插件之一即為:FireBug。FireBug是一個FireFox的插件,使用它,使前端開發(fā)人員丟棄了老舊的alert,F(xiàn)ireBug提供一個控制臺,開發(fā)人員可以直接像在windows的控制臺那樣,通過簡單的命令來查看變量的值,狀態(tài)等。

作為一個調(diào)試工具,F(xiàn)ireBug提供如其他IDE中那樣的基本功能,斷點(diǎn),步進(jìn),watch等等功能,下面我們來詳細(xì)介紹FireBug:

http://wiki.jikexueyuan.com/project/javascript-core/images/jsc4.png" alt="" />

通過在提示符”>>>”之后鍵入JavaScript代碼即可執(zhí)行這些代碼,由圖可見FireBug有6個標(biāo)簽:控制臺,HTML查看器,CSS查看器,腳本查看器,DOM查看器,以及網(wǎng)絡(luò)性能監(jiān)控。

http://wiki.jikexueyuan.com/project/javascript-core/images/jsc5.png" alt="" />

在FireBug處于“查看”狀態(tài)時,通過鼠標(biāo)在頁面上移動,頁面的一部分區(qū)域會高亮,點(diǎn)擊此高亮區(qū)域即進(jìn)入查看狀態(tài),注意此時FireBug的HTML查看窗口中的內(nèi)容:它會高亮顯示當(dāng)前選中區(qū)域的HTML代碼,而且你可以動態(tài)的編輯這些標(biāo)簽的屬性和樣式,對于頁面大小,風(fēng)格的微調(diào)十分有用。

http://wiki.jikexueyuan.com/project/javascript-core/images/jsc6.png" alt="" />

通過DOM查看器,我們可以清晰的看到頁面中所有JavaScirpt對象,而且是以樹的形式,可以逐層點(diǎn)開,查看詳情,這對于調(diào)試頁面非常有用。

http://wiki.jikexueyuan.com/project/javascript-core/images/jsc7.png" alt="" />

通過使用FireBug,我們就可以丟棄alert方式的調(diào)試了,F(xiàn)ireBug的調(diào)試與其他的IDE的使用非常類似,通過在代碼左側(cè)的行號旁邊單擊打斷點(diǎn),然后刷新頁面進(jìn)入調(diào)試環(huán)境,可以單步執(zhí)行,直接返回等。右側(cè)的面板上包含watch,棧情況,以及關(guān)于所有斷點(diǎn)的信息,調(diào)試起來非常方便。

FireBug的控制臺中常用的一些命令:

記錄日志,一般用于調(diào)試時將JavaScript字符串打印出來

console.log(object[, object, ...])  

打印消息,用于調(diào)試

console.info(obj)  

用于打印一個對象,將JavaScript對象的各個屬性樹以直觀的形式展現(xiàn)。

console.dir(obj)  
console.trace() 

Chrome

Chrome是Google的瀏覽器,渲染引擎為蘋果公司(Apple)的開源項(xiàng)目WebKit,而JavaScript引擎為V8,根據(jù)作者經(jīng)驗(yàn),Chrome為當(dāng)前瀏覽器界綜合性能最好的一款瀏覽器,無論是速度,資源的占用,響應(yīng)時間,以及界面,可擴(kuò)展性等方面,遠(yuǎn)遠(yuǎn)的超過了同儕。

Chrome一開始就附有開發(fā)人員工具,前端開發(fā)人員可以使用這個工具進(jìn)行類似與FireBug那樣對代碼進(jìn)行調(diào)試,同時可以動態(tài)增刪HTML屬性,查看頁面響應(yīng)時間,以便找出系統(tǒng)的瓶頸等。

像FireBug一樣,Chrome的內(nèi)置開發(fā)人員工具也可以查看JavaScript的運(yùn)行時結(jié)構(gòu),我們可以通過下面的一些圖例來看Chrome的調(diào)試工具的用法:

在chrome中,CTRL-SHIFT-I啟動開發(fā)人員工具:

http://wiki.jikexueyuan.com/project/javascript-core/images/jsc8.png" alt="" />

在console標(biāo)簽中,可以進(jìn)行一些腳本的測試:

http://wiki.jikexueyuan.com/project/javascript-core/images/jsc9.png" alt="" />

在實(shí)際的項(xiàng)目中,console系列的方法非常有用,特別是web容器如tomcat等返回的是復(fù)雜的JavaScript對象時,console.dir(object)可以直觀的讓開發(fā)人員看到對象的結(jié)構(gòu),非常便于調(diào)試。

客戶端的 MVC

MVC模型是在實(shí)際應(yīng)用中使用的較多的一種模式,它在很大程度上降低了整個應(yīng)用開發(fā)的復(fù)雜度。在J2EE應(yīng)用中,使用了MVC的框架不計其數(shù),比如structs,JSF等等。當(dāng)然MVC作為一種應(yīng)用程序的模型并不限制其使用的場景,比較著名的Swing工具包也是建立在MVC模型上的。

在MVC模型中,應(yīng)用被分為三個功能塊,M表示模型(Model),通常為后臺的數(shù)據(jù);V表示視圖(View),表示數(shù)據(jù)的展現(xiàn),如Web頁面或者2D庫渲染出來的其他UI組件,而C表示控制器(Controller),負(fù)責(zé)邏輯部分的控制,協(xié)調(diào)模型和視圖的關(guān)系。使用這個模型,可以降低個層次之間的耦合度,使得軟件可以較大程度上得到重用。

一般而言,MVC是構(gòu)建在整個系統(tǒng)中的,比如應(yīng)用的數(shù)據(jù)來自于遠(yuǎn)程數(shù)據(jù)庫或本地的文件系統(tǒng),視圖則在前端,直接展示給用戶,控制器部分則運(yùn)行在容器端。我們這個小節(jié)要討論的并不是這個結(jié)構(gòu),而是純粹建立在前端的MVC。

http://wiki.jikexueyuan.com/project/javascript-core/images/jsmvc.png" alt="" />

既然MVC模型的目的是降低層次間的耦合,降低開發(fā)的復(fù)雜度,使得軟件盡量的到重用,我們不妨建立這樣一套規(guī)則:

<!--[if !supportLists]-->l  <!--[endif]-->用HTML表示模型
<!--[if !supportLists]-->l  <!--[endif]-->用CSS來負(fù)責(zé)渲染視圖
<!--[if !supportLists]-->l  <!--[endif]-->用JavaScript負(fù)責(zé)控制前兩者

在HTML中,只是將文檔的結(jié)構(gòu)和內(nèi)容組織起來,通過CSS進(jìn)行渲染,布局等工作,而與用戶交互的部分則由JavaScript來控制,我們來看這樣一個例子:我們有一個頁面,其中有一個panel,當(dāng)點(diǎn)擊這個panel時其背景色會發(fā)生變化。

這個HTML文件看起來應(yīng)該是這樣的:

<html>  
    <head>  
        <script src="jquery-1.3.2.js" type="text/javascript" ></script>  
        <script src="controller.js" type="text/javascript"></script>  
        <link rel="stylesheet" href="style.css" type="text/css" />  
    </head>  
    <body>  
        <div class="contentGray" id="content">  
            This is the content of a panel  
        </div>  
    </body>  
</html>  

它引入了兩個腳本文件(控制器)和一個樣式表文件(視圖風(fēng)格),而HTML本身只不過定義了div的結(jié)構(gòu)和其位于body中的層次關(guān)系。

我們的視圖渲染部分:樣式表的內(nèi)容是這樣的:

.contentGray{  
    background : #ccc;  
    color : blue;  
    border : 1px solid black;  
    font: 13px 'Courier New';  
    width : 300px;  
    height : 30px;  
    padding-top : 10px;  
    padding-left : 10px;  
}  

.contentDark{  
    background : #666;  
    color : white;  
    border : 1px solid black;  
    font : 13px 'Courier New';  
    width : 300px;  
    height : 30px;  
    padding-top : 10px;  
    padding-left : 10px;      
}  

CSS文件定義了類(contentGray)的樣式及另外一個類(contentDark)的樣式,這樣HTML文件就可以看起來比較漂亮:

http://wiki.jikexueyuan.com/project/javascript-core/images/jsc10.png" alt="" />

我們的需求是,當(dāng)我們點(diǎn)擊這個panel的時候,它的背景色加深,文字變成白色,當(dāng)再次點(diǎn)擊的時候又恢復(fù)之前的顏色和背景色。這種“動態(tài)”的就交給JavaScript來處理了:

$(document).ready(function(){  
    $("div#content").click(function(){  
        $(this).toggleClass("contentDark");  
    })  
});  

使用jQuery可以為我們帶來很多便利,我們選擇id為content的div,然后注冊事件處理函數(shù),當(dāng)click事件發(fā)生的時候,我們就切換CSS類contentDark:

http://wiki.jikexueyuan.com/project/javascript-core/images/jsc11.png" alt="" />

當(dāng)然,這個只是一個簡單的例子,如果你的應(yīng)用所涉及的頁面比較多,而且控制器部分(JavaScript腳本)的工作量比較大,那么你會發(fā)現(xiàn),客戶端的MVC模型對你有很大的幫助,不但是界面的統(tǒng)一風(fēng)格,而且JavaScript代碼會更加模塊化,從而可能一定程度上提高應(yīng)用程序的效率,同時降低維護(hù)的難度。

Javascript/Ajax 框架

隨著富客戶端的流行,基于WEB的應(yīng)用越來越多,人們在開發(fā)過程中不再滿足于DOM提供的簡單API,特別是DOM對頁面的操作比較繁瑣,而且容易出錯。當(dāng)頁面越來越華麗,頁面UI越來越復(fù)雜(事件處理,特效處理)的時候,就有大量第三方JavaScript框架被開發(fā)出來了,比如較早的prototype,dojo,以及yahoo的YUI,后來的jQuery,以及jQuery的UI插件jQuery-UI,最早基于YUI而后來又進(jìn)行了重構(gòu)的ExtJs,號稱純OO的Mootools等等。

這些JavaScript框架的開發(fā),大大的簡化了頁面的開發(fā)速度,也提高了開發(fā)效率,同時比較注重用戶體驗(yàn),這里列舉出的框架幾乎都是完全免費(fèi),所以應(yīng)用十分廣泛。我們在隨后的兩章中將列舉兩個最流行的框架做一些介紹,以期讀者可以有一些感性的認(rèn)識,關(guān)于jQuery和ExtJS的深入的研究已經(jīng)大大的超出了本書的范圍(事實(shí)上每一個框架都足以寫一本書),有興趣的讀者可以參考相關(guān)的書籍。