2013-4-17 藍藍設計的小編
轉載藍藍設計( m.sillybuy.com )是一家專注而深入的設計機構 ,為期望卓越的國內外企業(yè)提供有效的 BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網(wǎng)站建設 、平面設計服務
來源:http://www.cnblogs.com/zhangziqiu/archive/2009/05/08/jQuery-Learn-9.html
如果您想訂閱本博客內容,每天自動發(fā)到您的郵箱中, 請點這里
一.摘要
本系列文章將帶您進入jQuery的精彩世界, 其中有很多作者具體的使用經(jīng)驗和解決方案, 即使你會使用jQuery也能在閱讀中發(fā)現(xiàn)些許秘籍.
我們經(jīng)常要使用腳本處理各種業(yè)務邏輯, 最常見的就是數(shù)組和對象的操作. jQuery工具函數(shù)為我們操作對象和數(shù)組提供了便利條件.
大部分人僅僅使用jQuery的選擇器選擇對象, 或者實現(xiàn)頁面動畫效果. 在處理業(yè)務邏輯時常常自己編寫很多算法. 本文提醒各位jQuery也能提高我們操作對象和數(shù)組的效率. 并且可以將一些常用算法擴充到jQuery工具函數(shù)中, 實現(xiàn)腳本函數(shù)的復用.
工具函數(shù)是指在jQuery對象(即變量"$")上定義的函數(shù). 這些函數(shù)都是工具類函數(shù).比如C#中最常用的trim()函數(shù):
$.trim(" text ");
在原始javascript中并沒有提供同時去除前后空格的trim函數(shù). 所以這一類常用的工具函數(shù)統(tǒng)稱為 "Utilities" 函數(shù).對應jQuery官方文檔:
http://docs.jquery.com/Utilities
"$"其實是"window"對象的屬性, 所以下面幾句話是等價的:
$.trim(" text "); window.$.trim(" text "); window.jQuery(" text "); jQuery.trim(" text ");
工具函數(shù)主要分為下面幾類:
區(qū)別于前幾章的講解方式, 本文不在列舉函數(shù)列表. 大家在應用中, 比如遇到想操作一個字符串, 可以首先從在"API文檔/Utilities/字符串操作"中查找是否已經(jīng)提供了快捷的工具函數(shù). 如果沒有再考慮自己開發(fā).
下面使用實例具體的每個分類下常用的工具函數(shù).
jQuery的優(yōu)秀就在于其跨瀏覽器的特性, 通常我們不用再針對不同瀏覽器書寫不同的代碼. 但是如果是jQuery開發(fā)人員或者插件開發(fā)人員就要自行處理瀏覽器差異, 以便為用戶提供跨瀏覽器的特性.
jQuery提供了下列屬性用于獲取瀏覽器特性:
1.3版本新增 | |
jQuery.browser | 已廢除 |
已廢除 | |
jQuery.boxModel | 已廢除 |
在1.3版本中已經(jīng)廢除了三個屬性, 這里不再講解. 讓我們將注意力放在 jQuery.support 函數(shù)上.
返回值: Object
說明:
jQuery 1.3 新增。一組用于展示不同瀏覽器各自特性和bug的屬性集合。
jQuery提供了一系列屬性,你也可以自由增加你自己的屬性。其中許多屬性是很低級的,所以很難說他們能否在日新月異的發(fā)展中一直保持有效,但這這些主要用于插件和內核開發(fā)者。
所有這些支持的屬性值都通過特性檢測來實現(xiàn),而不是用任何瀏覽器檢測。以下有一些非常棒的資源用于解釋這些特性檢測是如何工作的:
jQuery.support主要包括以下測試:
boxModel: 如果這個頁面和瀏覽器是以W3C CSS盒式模型來渲染的,則等于true。通常在IE 6和IE 7的怪癖模式中這個值是false。在document準備就緒前,這個值是null。
cssFloat: 如果用cssFloat來訪問CSS的float的值,則返回true。目前在IE中會返回false,他用styleFloat代替。
hrefNormalized: 如果瀏覽器從getAttribute("href")返回的是原封不動的結果,則返回true。在IE中會返回false,因為他的URLs已經(jīng)常規(guī)化了。
htmlSerialize: 如果瀏覽器通過innerHTML插入鏈接元素的時候會序列化這些鏈接,則返回true,目前IE中返回false。
leadingWhitespace: 如果在使用innerHTML的時候瀏覽器會保持前導空白字符,則返回true,目前在IE 6-8中返回false。
noCloneEvent: 如果瀏覽器在克隆元素的時候不會連同事件處理函數(shù)一起復制,則返回true,目前在IE中返回false。
objectAll: 如果在某個元素對象上執(zhí)行getElementsByTagName("*")會返回所有子孫元素,則為true,目前在IE 7中為false。
opacity: 如果瀏覽器能適當解釋透明度樣式屬性,則返回true,目前在IE中返回false,因為他用alpha濾鏡代替。
scriptEval: 使用 appendChild/createTextNode 方法插入腳本代碼時,瀏覽器是否執(zhí)行腳本,目前在IE中返回false,IE使用 .text 方法插入腳本代碼以執(zhí)行。
style: 如果getAttribute("style")返回元素的行內樣式,則為true。目前IE中為false,因為他用cssText代替。
tbody: 如果瀏覽器允許table元素不包含tbody元素,則返回true。目前在IE中會返回false,他會自動插入缺失的tbody。
講解:
針對上面眾多的瀏覽器特性屬性, 本文只講解兩個特性.
下圖是W3C標準中的盒式模型圖:
假設如下元素:
<style type="text/css"> .boxModel { width:200px; height:50px; padding:10px; border:solid 5px #FF0000; background-color:#acacac; }</style> <div id="divBox" class="boxModel">
顯示效果如圖:
在CSS中設定元素寬度為200px, 下面以此元素為例講解盒式模式.
元素的寬度和高度為盒式模型圖中的Context部分, 不包括padding, border和margin部分.
目前除了IE所有的瀏覽器都僅支持W3C盒式模型. 在W3C盒式模型中, 示例中包含紅框在內的區(qū)域內容寬度為200+2*10+2*5=230px, 高度為50+2*10+2*5=80px.
設置的寬度包括padding,border. 實際內容寬度content Width = width - padding – border
在IE5.5及更早的版本中, 使用了此模型. 在更高的IE版本上如果由于某些原因讓瀏覽器運行在怪異模式下則也會使用此盒式模式.所以需要在頁面上聲明正確的DOCTYPE. 有關DOCTYPE請參考此文:
http://www.cnblogs.com/zhangziqiu/archive/2009/01/15/doctype.html
下面是兩種盒式模式的對比:
我們可以使用 jQuery.support.boxModel 屬性來獲取瀏覽器是否使用了W3C盒式模型. true表示使用W3C boxModel.
通過javascript腳本設置元素的float樣式時, IE和FireFox存在不同, IE使用style.styleFloat, FireFox使用style.cssFloat:
div.style.styleFloat = "left"; //IE div.stlye.cssFloat = "left"; //FF
jQuery.support.cssFloat 屬性返回true則表示可以使用cssFloat來設置float樣式. IE中返回false;
注意, 我們可以通過CSS()方法設置float樣式, jQuery內部會自動幫我們判斷是使用styleFloat還是cssFloat:
$("#divResult").css("float","left"); //兼容IE和FF
實現(xiàn)UI我們常常操作DOM對象或者jQuery包裝集, 但是實現(xiàn)算法或者業(yè)務邏輯時往往操作的是數(shù)組和對象.
下面講解最常用的數(shù)組和對象相關的工具函數(shù).
jQuery.each( object, callback )
返回值:Object
說明:
通用例遍方法,可用于例遍對象和數(shù)組。
不同于例遍 jQuery 對象的 $().each() 方法,此方法可用于例遍任何對象。回調函數(shù)擁有兩個參數(shù):第一個為對象的成員或數(shù)組的索引,第二個為對應變量或內容。如果需要退出 each 循環(huán)可使回調函數(shù)返回 false,其它返回值將被忽略。
講解:
對于jQuery包裝集我們可以使用each(callback)方法迭代包裝集中的每一個元素. callback是一個會函數(shù), 接受一個參數(shù)表示當前訪問對象的索引.
$("img").each(function(i){ this.src = "test" + i + ".jpg"; });
對于數(shù)組我們可以使用 jQuery.each( object, callback ) 來遍歷, 這等同于使用for循環(huán).
注意傳入的第一個參數(shù)可以是數(shù)組或者對象.如果數(shù)組,則遍歷數(shù)組中的每一個對象. 第一個參數(shù)表示索引,第二個參數(shù)表示值, this表示當前遍歷的元素, 可以通過返回false終止迭代, 比如下面的示例遍歷到第二個元素后會終止:
$.each(["a", "b", "c"], function(i, n) { alert("Item #" + i + ": " + n);//可以獲取到i值 if (i >= 1) { return false; } });
$("#iterateArray").click(function(event) { var array = $.each(["a", "b", "c"], function(i, n) { alert("Item #" + i + ": " + n ); //第一個參數(shù)i表示索引, this表示當前遍歷的對象 if (i >= 1) { return false; } }); });
如果傳遞的是對象, 則遍歷對象的每一個屬性, 即使函數(shù)返回false也依然會遍歷完所有的屬性, 第一個參數(shù)表示屬性key(屬性名稱,是obejct類型),第二個參數(shù)表示值,,this表示當前屬性的值:
$("#iterateObject").click(function(event) { $.each({ name: "ziqiu.zhang", sex: "male", status: "single" }, function(i, n) { alert("Item #" + i.toString() + ": " + n ); //第一個參數(shù)i表示屬性的key(object), this表示屬性值 if (i >= 1) { return false; } }); });
each將是我們最常使用的函數(shù), 特別注意each雖然迭代每一個元素或屬性, 但是在迭代函數(shù)中并不會改變當前元素的值, 也就是無法改變返回后的對象.如果需要改變數(shù)組中的每一個元素并且將結果返回, 因使用jQuery.map( array, callback )函數(shù).
jQuery.grep( array, callback, [invert] )
返回值: Array
說明:
使用過濾函數(shù)過濾數(shù)組元素。
此函數(shù)至少傳遞兩個參數(shù):待過濾數(shù)組和過濾函數(shù)。過濾函數(shù)必須返回 true 以保留元素或 false 以刪除元素。
講解:
默認invert為false, 即過濾函數(shù)返回true為保留元素. 如果設置invert為true, 則過濾函數(shù)返回true為刪除元素.
下面的示例演示如何過濾數(shù)組中索引小于 0 的元素:
$.grep( [0,1,2], function(n,i){ return n > 0; });
返回的結果是[1,2]
返回值:Array
說明:
將一個數(shù)組中的元素轉換到另一個數(shù)組中。
作為參數(shù)的轉換函數(shù)會為每個數(shù)組元素調用,而且會給這個轉換函數(shù)傳遞一個表示被轉換的元素作為參數(shù)。轉換函數(shù)可以返回轉換后的值、null(刪除數(shù)組中的項目)或一個包含值的數(shù)組,并擴展至原始數(shù)組中。
講解:
1.3.2版本中此函數(shù)和each函數(shù)已經(jīng)幾乎相同(以前稍有不同), 現(xiàn)在唯一的區(qū)別就是回調函數(shù)可以改變當前元素.返回null則刪除當前元素.
下面是幾個例子:
var arr = [ "a", "b", "c", "d", "e" ] $("div").text(arr.join(", ")); arr = jQuery.map(arr, function(n, i){ return (n.toUpperCase() + i); }); $("p").text(arr.join(", ")); arr = jQuery.map(arr, function (a) { return a + a; }); $("span").text(arr.join(", "));
合并對象是我們常常編寫的功能, 通常使用臃腫的for循環(huán)來進行.jQuery為我們提供了很多功能的合并函數(shù):
名稱 | 說明 | 舉例 |
jQuery.extend( [deep], target, object1, [objectN] ) |
用一個或多個其他對象來擴展一個對象,返回被擴展的對象。 如果不指定target,則給jQuery命名空間本身進行擴展。這有助于插件作者為jQuery增加新方法。 如果第一個參數(shù)設置為true,則jQuery返回一個深層次的副本,遞歸地復制找到的任何對象。否則的話,副本會與原對象共享結構。 為定義的屬性將不會被復制,然而從對象的原型繼承的屬性將會被復制。 |
合并 settings 和 options,修改并返回 settings: var settings = { validate: false, limit: 5, name: "foo" }; 結果: settings == { validate: true, limit: 5, name: "bar" } |
將類數(shù)組對象轉換為數(shù)組對象。 類數(shù)組對象有 length 屬性,其成員索引為 0 至 length - 1。實際中此函數(shù)在 jQuery 中將自動使用而無需特意轉換。 |
將DOM對象集合轉換為數(shù)組: var arr = jQuery.makeArray(document.getElementsByTagName("div")); |
|
jQuery.inArray( value, array ) | 確定第一個參數(shù)在數(shù)組中的位置,從0開始計數(shù)(如果沒有找到則返回 -1 )。 | 查看對應元素的位置:
|
jQuery.merge( first, second ) |
合并兩個數(shù)組 返回的結果會修改第一個數(shù)組的內容——第一個數(shù)組的元素后面跟著第二個數(shù)組的元素。要去除重復項,請使用$.unique() |
合并兩個數(shù)組到第一個數(shù)組上: $.merge( [0,1,2], [2,3,4] ) 結果:
|
jQuery.unique( array ) | 刪除數(shù)組中重復元素。只處理刪除DOM元素數(shù)組,而不能處理字符串或者數(shù)字數(shù)組。 | 刪除重復 div 標簽: $.unique(document.getElementsByTagName("div"));
|
講解:
上面的函數(shù)看著有些混亂. 看看我們以后會常用的.
首先是jQuery.merge( first, second ), 將兩個數(shù)組合并. 下面這個示例說明如何使用此函數(shù):
<html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>jQuery Utilities - jQuery.merge</title> <script src="../scripts/jquery-1.3.2-vsdoc2.js" type="text/javascript"></script> <script type="text/javascript"> $(function() { $("#go").click(function(event) { $("#divResult").html(""); var first = [1, 3, 5]; $("#divResult").append("<span>first:[" + first.join(",") + "]</span>").append("<br/>"); var second = [2, 4, 6]; $("#divResult").append("<span>second:[" + second.join(",") + "]</span>").append("<br/>"); var result = $.merge(first, second); $("#divResult").append("<span>result:[" + result.join(",") + "]</span>").append("<br/>"); $("#divResult").append("<span>first after merged:[" + first.join(",") + "]</span><br/>"); $("#divResult").append("<span>second after merged:[" + second.join(",") + "]</span><br/>"); }); }); </script> </head> <body> <button id="go"> 合并數(shù)組</button> <br /> <div id="divResult"> </div> </body> </html>
結果如圖:
另外不能因為有了jQuery就忘記我們的原始javascript. 比merge更常用的其實是join和split函數(shù).
merge函數(shù)會改變第一個合并的數(shù)組, 如果是我設計我就不會這么做. 因為返回值已經(jīng)是合并后的數(shù)組了.如此設計讓函數(shù)產生歧義.
列表中的那么多函數(shù)不再一一講解. 先用先查. 除了 jQuery.extend 這個不得不提的函數(shù). 下面單提一個小結講解.
在開發(fā)插件的時候最常用此函數(shù)函數(shù)來處理options.
下面是fancybox插件獲取options的代碼:
settings = $.extend({}, $.fn.fancybox.defaults, settings);
上面的代碼target是一個空對象, 將默認設置defaults作為第一個對象, 將用戶傳入的設置setting合并到default上, setting上有的屬性以setting為準. setting沒有傳入的屬性則使用default的默認值. 然后將合并的結果復制給target并作為函數(shù)返回值返回.
看一個完整的示例:
var empty = {}var defaults = { validate: false, limit: 5, name: "foo" };var options = { validate: true, name: "bar" };var settings = jQuery.extend(empty, defaults, options);
結果:
settings == { validate: true, limit: 5, name: "bar" } empty == { validate: true, limit: 5, name: "bar" }
target參數(shù)要傳遞一個空對象是因為target的值最后將被改變.比如:
var defaults = { validate: false, limit: 5, name: "foo" }; var options = { validate: true, name: "bar" }; var settings = jQuery.extend(defaults, options);
上面的代碼將defaults作為target參數(shù), 雖然最后settings的結果一樣, 但是defaults的值被改變了! 而插件中的默認值應該都是固定! 所以使用時請注意target參數(shù)的用法.
下面是我的完整示例和結果:
<html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>jQuery Utilities - jQuery.extend</title> <script src="../scripts/jquery-1.3.2-vsdoc2.js" type="text/javascript"></script> <script type="text/javascript"> $.toObjectString = function (obj) { var result = "{"; var counter = 0; $.each(obj, function(i, n) { if (counter > 0) { result += ","; } result += i.toString() + ":" + n.toString(); counter++; }); result += "}"; return result; } $(function() { $("#go1").click(function(event) { $("#divResult").html(""); var empty = {} var defaults = { validate: false, limit: 5, name: "foo" }; var options = { validate: true, name: "bar" }; $("#divResult").append("<span>empty:" + $.toObjectString(empty) + "</span>").append("<br/>"); $("#divResult").append("<span>defaults:" + $.toObjectString(defaults) + "</span>").append("<br/>"); $("#divResult").append("<span>options:" + $.toObjectString(options) + "</span>").append("<br/>"); var settings = jQuery.extend(empty, defaults, options); $("#divResult").append("<span>settings after extend:" + $.toObjectString(settings) + "</span>").append("<br/>"); $("#divResult").append("<span>defaults after extend:" + $.toObjectString(defaults) + "</span>").append("<br/>"); $("#divResult").append("<span>options after extend:" + $.toObjectString(options) + "</span>").append("<br/>"); }); $("#go2").click(function(event) { $("#divResult").html(""); var defaults = { validate: false, limit: 5, name: "foo" }; var options = { validate: true, name: "bar" }; $("#divResult").append("<span>defaults:" + $.toObjectString(defaults) + "</span>").append("<br/>"); $("#divResult").append("<span>options:" + $.toObjectString(options) + "</span>").append("<br/>"); var settings = jQuery.extend(defaults, options); $("#divResult").append("<span>settings after extend:" + $.toObjectString(settings) + "</span>").append("<br/>"); $("#divResult").append("<span>defaults after extend:" + $.toObjectString(defaults) + "</span>").append("<br/>"); $("#divResult").append("<span>options after extend:" + $.toObjectString(options) + "</span>").append("<br/>"); }); }); </script> </head> <body> <button id="go1" style="height:40px;width:400px;"> jQuery.extend(empty, defaults, options)</button> <button id="go2" style="height:40px;width:400px;"> jQuery.extend(defaults, options)</button> <br /> <div id="divResult"> </div> </body> </html>
結果:
測試工具函數(shù)主要用于判斷對象是否是某一種類型, 返回的都是Boolean值:
同時別忘記了javascript中自帶的isNaN和isFinite:
var test = "123"; alert(isNaN(test)); alert(isFinite(test));
isNaN函數(shù)判斷參數(shù)是否是非數(shù)字. 如果是數(shù)字則返回false.
isFinite函數(shù)檢查其參數(shù)是否是無窮大.如果參數(shù)是 NaN(非數(shù)字),或者是正、負無窮大的數(shù),則返回 false.否則返回true.
目前核心類庫中只有一個字符串工具函數(shù):
返回值: string
說明:去掉字符串起始和結尾的空格。
舉例:
去掉字符串起始和結尾的空格:
$.trim(" hello, how are you? ");
結果:
"hello, how are you?"
返回值:string
說明:
將表單元素數(shù)組或者對象序列化。是.serialize()的核心方法。
數(shù)組或jQuery對象會按照name/value對進行序列化,普通對象按照key/value對進行序列化
舉例:
var params = { width:1680, height:1050 }; var str = jQuery.param(params); $("#results").text(str);
結果:
width=1680&height=1050
jQuery將其歸為Urls分類, 因為此方法通常用于發(fā)送GET請求時將對象作為urls參數(shù)傳遞給服務端.
擴展工具函數(shù)只需要對jQuery(即"$")進行擴展. 通常開發(fā)工具函數(shù)或者插件的人希望在開發(fā)時使用"$", 但因為"$"有可能和其他腳本庫沖突, 所以通常我們使用下面的語法開發(fā)工具函數(shù):
(function($) { $.myExtendMethod = function(o) { alert(0); }; })(jQuery);
在函數(shù)體內的"$"能保證是代表jQuery對象.
然后使用這種方式開發(fā)不能享受到智能感知的便利. 一般我們將擴展工具函數(shù)和擴展jQuery包裝集函數(shù)都放在一個單獨的文件中.
下面這個示例演示如何添加自定義的jQuery工具方法和jQuery包裝集方法:
/// <reference path="jquery-1.3.2-vsdoc2.js" /> jQuery.myExtendMethod = function(o) { /// <summary> /// 擴展方法注釋. /// </summary> /// <param name="o" type="String">參數(shù)提示文字</param> /// <returns type="string" >返回值提示文字</returns> alert(0); }; jQuery.fn.myExtendMethod = function(o) { /// <summary> /// 擴展方法注釋. /// </summary> /// <param name="o" type="String">參數(shù)提示文字</param> /// <returns type="string" >返回值提示文字</returns> alert(0); };
通過第一行reference, 我們可以在此js文件中繼續(xù)使用jQuery腳本智能感知.
jQuery.myExtendMethod方法擴展的工具函數(shù).
jQuery.fn.myExtendMethod方法擴展的是jQuery包裝集函數(shù), 即為使用$()獲取到的對象添加了方法.
同理使用XML注釋, 比如<summary> 還可以為自定義方法添加智能感知提示.腳本中的XML注釋和.NET中的一樣, 有關.NET中的XML注釋可以參考我的另外一篇文章:
jQuery提供了許多的工具函數(shù), 在一般情況下可以滿足我們的需要. 但是對于像JSON格式化一類的操作, 需要我們自己擴展, 現(xiàn)有的各種擴展組件資源將提高我們的開發(fā)效率, 本系列Ajax章節(jié)就介紹的一個JSON序列化的組件jQuery.json. 更多的組件需要大家在工作中挖掘.
藍藍設計(北京蘭亭妙微科技有限公司)是一家專注而深入的設計機構 ,為期望卓越的國內外企業(yè)提供有效的視覺設計、ui界面設計、網(wǎng)站建設、用戶體驗服務,涉及互聯(lián)網(wǎng)、IT軟件、電子、銀行、保健品等多個行業(yè),并建立了良好的口碑,積累了豐富的經(jīng)驗。
全國統(tǒng)一服務熱線 400-608-6026 QQ:896757335
在確認了沒有公布任何保密信息后, 我發(fā)表了本文. 沒有太多技術含量, 主要是針對所在公司推廣jQuery的具體實施方法.
另外我一直想找一個成型的腳本框架用來組織管理各種js類庫和js文件. 這都需要在以后的工作中探索.