讀《從零開始學習jQuery》要點摘要供複習記憶

注意jQuery是腳本庫, 而不是腳本框架. "庫"不等於"框架", 比如"System程序集"是類庫,而"ASP.NET MVC"是框架. jQuery並不能幫助我們解決腳本的引用管理和功能管理,這些都是腳本框架要做的事。

 

1.下載jQuery類庫

jQuery的項目下載放在了Google Code上, 下載地址:http://code.google.com/p/jqueryjs/downloads/list

 

上面的地址是總下載列表, 裏面有很多版本和類型的jQuery庫, 主要分爲如下幾類:

min: 壓縮後的jQuery類庫,  在正式環境上使用.如:jquery-1.3.2.min.js

vsdoc: 在Visual Studio中需要引入此版本的jquery類庫才能啓用智能感知.如:jquery-1.3.2-vsdoc2.js

release包: 裏面有沒有壓縮的jquery代碼, 以及文檔和示例程序. 如:jquery-1.3.2-release.zip

 

五.啓用Visual Studio 對jQuery的智能感知

首先看一下Visual Studio帶給我們的智能感知驚喜. 要讓Visual Studio支持智能感知, 需要下列條件:

  • 安裝 VS2008 SP1
    下載地址: http://msdn.microsoft.com/en-us/vstudio/cc533448.aspx
  • 安裝VS 2008 Patch KB958502以支持"-vsdoc.js"Intellisense文件.
    該補丁會導致VisualStudio在一個JavaScript庫被引用時,查找是否存在一個可選的"-vsdoc.js"文件,如果存在的話,就用它來驅動JavaScriptintellisense引擎。這些加了註釋的"-vsdoc.js"文件可以包含對JavaScript方法提供了幫助文檔的XML註釋,以及對無法自動推斷出的動態JavaScript簽名的另外的代碼intellisense提示。你可以在"這裏"瞭解該補丁的詳情。你可以在"這裏"免費下載該補丁。
  • 必須要引用vsdoc版本的jquery庫 

注意,如果我們更新了腳本, 可以通過"Ctrl+Shift+J"快捷方式更新Visual Studio的智能感知,或者單擊 編輯->IntelliSense->更新JScript Intellisense.

 

爲了即能在Visual Studio中增加腳本提示, 又能在上線的時候使用min版本的腳本庫, 我們一般是用如下方式引入jQuery庫:

<script type="text/javascript" src="scripts/jquery-1.2.6.min.js"></script>
<%if (false){%>
<script type="text/javascript" src="scripts/jquery-1.3.2-vsdoc2.js">  </script>   
<%}%>

 

在獨立的.js文件中我們同樣可以啓用腳本的智能感知, 在IntellisenseDemo.js文件中,添加如下語句:
/// <reference path="jquery-1.3.2-vsdoc2.js" />

 

1.Dom對象

在傳統的javascript開發中,我們都是首先獲取Dom對象,比如:
var div = document.getElementById("testDiv");
var divs = document.getElementsByTagName("div");

我們經常使用 document.getElementById 方法根據id獲取單個Dom對象, 或者使用 document.getElementsByTagName 方法根據HTML標籤名稱獲取Dom對象集合.

另外在事件函數中, 可以通過在方法函數中使用this引用事件觸發對象(但是在多播事件函數中IE6存在問題), 或者使用event對象的target(FF)或srcElement(iIE6)獲取到引發事件的Dom對象.
注意我們這裏獲取到的都是Dom對象, Dom對象也有不同的類型比如input, div, span等. Dom對象只有有限的屬性和方法。

2.jQuery包裝集

jQuery包裝集可以說是Dom對象的擴充.在jQuery的世界中將所有的對象, 無論是一個還是一組, 都封裝成一個jQuery包裝集,比如獲取包含一個元素的jQuery包裝集:
var jQueryObject = $("#testDiv");
jQuery包裝集都是作爲一個對象一起調用的. jQuery包裝集擁有豐富的屬性和方法, 這些都是jQuery特有的。

3.Dom對象與jQuery對象的轉換


(1) Dom轉jQuery包裝集
var div = document.getElementById("testDiv");
上面的代碼中div是一個Dom元素, 我們可以將Dom元素轉換成jQuery包裝集:
var domToJQueryObject = $(div);

(2) jQuery包裝集轉Dom對象
jQuery包裝集是一個集合, 所以我們可以通過索引器訪問其中的某一個元素:
var domObject = $("#testDiv")[0];
注意, 通過索引器返回的不再是jQuery包裝集, 而是一個Dom對象!

jQuery包裝集的某些遍歷方法,比如each()中, 可以傳遞遍歷函數, 在遍歷函數中的this也是Dom元素,比如:
$("#testDiv").each(function() { alert(this) })

如果我們要使用jQuery的方法操作Dom對象,怎麼辦? 用上面介紹過的轉換方法即可:
$("#testDiv").each(function() { $(this).html("修改內容") })

"$"符號在jQuery中代表對jQuery對象的引用, "jQuery"是核心對象。
jQuery( expression, context ) 這個函數接收一個CSS選擇器的字符串,然後用這個字符串去匹配一組元素。
jQuery( html, ownerDocument ) 根據HTML原始字符串動態創建Dom元素.
jQuery( elements ) 將一個或多個Dom對象封裝jQuery函數功能(即封裝爲jQuery包裝集)
jQuery( callback )是$(document).ready()的簡寫方式

jQuery選擇器按照功能主要分爲"選擇"和"過濾". 並且是配合使用的. 可以同時使用組合成一個選擇器字符串. 主要的區別是"過濾"作用的選擇器是指定條件從前面匹配的內容中篩選, "過濾"選擇器也可以單獨使用, 表示從全部"*"中篩選. 比如:
$(":[title]") 等同於:$("*:[title]")
而"選擇"功能的選擇器則不會有默認的範圍, 因爲作用是"選擇"而不是"過濾".
過濾器前面帶冒號,如::first
屬性過濾器用方括號包括起來,如:[attribute!=value]

永遠不要在頁面加載時改變頁面的Dom模型,如下:
<script type="text/javascript">
    document.getElementById("testDiv").innerHTML = "動態創建的div";
</script>
正確的做法是在頁面加載完畢後添加或刪除元素:
//DOM加載完畢後添加元素
//傳統方法
window.onload = function() { testDiv.innerHTML = "動態創建的div"; }
不幸的是瀏覽器執行window.onload函數不僅僅是在構建完DOM樹之後, 也是在所有圖像和其他外部資源完整的加載並且在瀏覽器窗口顯示完畢之後.
解決辦法就是等DOM被解析後, 在圖像和外部資源加載之前執行我們的函數.在jQuery中讓這一實現變得可行:
//jQuery 使用動態創建的$(document).ready(function)方法
$(document).ready(
    function() { testDiv.innerHTML = "使用動態創建的$(document).ready(function)方法"; }
);
或者使用簡便語法:
//jQuery 使用$(function)方法
$(
    function() { testDiv.innerHTML += "使用$(function)方法"; }
);
使用$()將我們的函數包裝起來即可,而且可以在一個頁面綁定多個函數。如果使用傳統的window.onload則只能調用一個函數.

下面介紹兩種正確的創建元素的方式.
(1)使用HTML DOM創建元素
通過使用 document.createElement 方法我們可以創建Dom元素, 然後通過appendChild方法爲添加到指定對象上.
//使用Dom標準創建元素
var select = document.createElement("select");
select.options[0] = new Option("加載項1", "value1");
select.options[1] = new Option("加載項2", "value2");
select.size = "2";
var object = testDiv.appendChild(select);

(2) 使用jQuery函數創建元素
$("
動態創建的div
")

區分DOM屬性和元素屬性
一個img標籤:<img src="images/image.1.jpg" id="hibiscus" alt="Hibiscus" class="classA" />
通常開發人員習慣將id, src, alt等叫做這個元素的"屬性". 我將其稱爲"元素屬性". 但是在解析成DOM對象時, 實際瀏覽器最後會將標籤元素解析成"DOM對象", 並且將元素的"元素屬性"存儲爲"DOM屬性"。兩者是有區別的:
雖然我們設置了元素的src是相對路徑:images/image.1.jpg
但是在"DOM屬性"中都會轉換成絕對路徑:http://localhost/images/image.1.jpg.
甚至有些"元素屬性"和"DOM屬性"的名稱都不一樣,比如上面的元素屬性class, 轉換爲DOM屬性後對應className.

操作"DOM屬性"
牢記, 在javascript中我們可以直接獲取或設置"DOM屬性"。
在jQuery中沒有包裝操作"DOM屬性"的函數, 因爲使用javascript獲取和設置"DOM屬性"都很簡單. 在jQuery提供了each()函數用於遍歷Query
包裝集, 其中的this指針是一個DOM對象, 所以我們可以應用這一點配合原生javascript來操作元素的DOM屬性。
$("img").each(function(index) {
    alert("index:" + index + ", id:" + this.id + ", alt:" + this.alt);
    this.alt = "changed";
    alert("index:" + index + ", id:" + this.id + ", alt:" + this.alt);
});

操作"元素屬性"
我們可以使用javascript中的getAttribute和setAttribute來操作元素的"元素屬性"。
在jQuery中給你提供了attr()包裝集函數, 能夠同時操作包裝集中所有元素的屬性。
另外雖然我們可以使用 removeAttr( name ) 刪除元素屬性, 但是對應的DOM屬性是不會被刪除的, 只會影響DOM屬性的值.
比如將一個input元素的readonly元素屬性去掉,會導致對應的DOM屬性變成false(即input變成可編輯狀態):
$("#inputTest").removeAttr("readonly");

雖然我們可以通過獲取屬性,特性以及CSS樣式來取得元素的幾乎所有信息,  但是注意下面的實驗:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtm
l1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>獲取對象寬度</title>
    <script type="text/javascript" src="scripts/jquery-1.3.2-vsdoc2.js"></script>
    <script type="text/javascript">
        $(function()
        {
            alert("attr(/"width/"):" + $("#testDiv").attr("width")); //undifined
            alert("css(/"width/"):" + $("#testDiv").css("width")); //auto(ie6) 或 1264px(ff)
            alert("width():" + $("#testDiv").width()); //正確的數值1264
            alert("style.width:" +  $("#testDiv")[0].style.width ); //空值
        })
    </script>
</head>
<body>
    <div id="testDiv">
        測試文本</div>
</body>
</html>

 

我們常用的修改元素屬性添加事件的方式, 實際上是建立了一個匿名函數:
document.getElementById("testDiv1").onclick = function(event)
{
    alert("!!!");
};
這種方式的弊端是:
1. 只能爲一個事件綁定一個事件處理函數.  使用"="賦值會把前面爲此時間綁定的所有事件處理函數沖掉。
2. 在事件函數(無論是匿名函數還是綁定的函數)中獲取事件對象的方式在不同瀏覽器中要特殊處理。

3. 添加多播委託的函數在不同瀏覽器中是不一樣的.
//統一的爲對象添加多播事件委託的方法
/* 
    參數說明:
    oTarget     : 要添加事件的對象.比如"document".
    sEventType  : 事件類型.比如單擊事件"click".
    fnHandler   : 發生事件時調用的方法. 比如一個靜態函數"hideCalendar"
   
    使用舉例:
    //單擊頁面的任何元素,只要沒有取消冒泡,都可以關閉日曆控件
    var cf = document.getElementById("CalFrame");
    if( cf != null && hideCalendar != null )
    {
        ScriptHelper.addEventListener( document, "click", hideCalendar );
    }
*/
scriptHelper.prototype.addEventListener = function(oTarget, sEventType, fnHandler)
{
    if( oTarget.addEventListener )//for dom
    {
        oTarget.addEventListener( sEventType, fnHandler, false )
    }
    else if( oTarget.attachEvent )//for ie
    {
        oTarget.attachEvent( "on" + sEventType, fnHandler);
    }
}
所以我們首先應該摒棄<div onclick="..."></div>這種通過修改元素屬性添加事件的方式. 儘量使用添加多播事件委託的方式爲一個事件綁定多個事件處理函數, 比如爲document對象的單擊事件添加一個關閉彈出層的方法, 使用多播就不會影響document對象原有的事件處理函數.

 

使用jQuery事件處理函數的好處:
1. 添加的是多播事件委託.  也就是爲click事件又添加了一個方法, 不會覆蓋對象的click事件原有的事件處理函數.
2. 統一了事件名稱. 
3. 可以將對象行爲全部用腳本控制.

雖然我們可以使用事件處理函數完成對象事件的幾乎所有操作, 但是jQuery提供了對常用事件的封裝. 比如單擊事件對應的兩個方法click()和click(fn)分別用來觸發單擊事件和設置單擊事件.

jQuery中統一了事件對象,  當綁定事件處理函數時,  會將jQuery格式化後的事件對象作爲唯一參數傳入:
$("#testDiv").bind("click", function(event) {  });//event是事件對象
jQuery事件對象將不同瀏覽器的差異進行了合併, 比如可以在所有瀏覽器中通過 event.target 屬性來獲取事件的觸發者(在IE中使用原生的事件對象, 需要訪問event.srcElement).

事件對象除了擁有屬性, 還擁有事件. 有一些是一定會用到的事件比如取消冒泡 stopPropagation() 等.

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章