精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

jQuery高級應用:優(yōu)化Web應用程序的最后絕招

開發(fā) 開發(fā)工具 前端
在本文中,我將討論代碼的性能改進,同時也談及一些關于jQuery庫的容易被忽視的問題。有些東西對于復雜的應用程序而言至關重要,即對所有應用程序都非常關鍵的插件,以及使應用程序的編寫更加容易的良好設計技巧。

jQuery讓編寫基于JavaScript的良好Web應用程序變得簡單明了,但是要想將好的Web應用程序變得更出色還需要額外幾個步驟。本文詳細闡述幾個讓Web應用程序變得更強大的步驟,這些步驟是優(yōu)化您的Web應用程序的***絕招。

51CTO推薦專題:jQuery從入門到精通

***個示例應用程序

***個示例應用程序

本文中的大部分技巧都可以從附帶的樣例應用程序中找到,這是一個直觀的電子郵件Web應用程序。不過,您可以看到它是如何從***篇文章中發(fā)展而來的,它的性能是如何改進的,以及這些***步驟如何將它轉(zhuǎn)變成強大的Web應用程序的。

Bind/Unbind

在Events模塊中有兩個函數(shù),它們是bind()和unbind(),用于完成所有其他事件方法的任務。如果您能夠向頁面元素添加一個click()方法,那么哪還有必要調(diào)用bind("click")呢?這僅是浪費時間而已。但是,這些函數(shù)在特定情況下是非常方便的,如果正確地使用它們,可以顯著提高應用程序的性能。

Bind/Unbind

這些函數(shù)不僅能夠向特定頁面元素添加事件(就像該模塊中的許多其他事件方法一樣),而且還可以從頁面元素中刪除這些事件。為什么要這樣做?下面我們看看這個Web應用程序,以及如何在特定情況下使用這些函數(shù)。

清單1顯示了以上設置的代碼,這是未改進之前的原始代碼:

  1. $(document).ready(function(){  
  2. //cachethisquerysinceit'sasearchbyCLASS  
  3. selectable=$(":checked.selectable");  
  4. //whentheselect/deselectallisclicked,dothisfunction  
  5. $("#selectall").click(selectAll);  
  6. //wheneveranyindividualcheckboxischecked,changethetext  
  7. //describinghowmanyarechecked  
  8. selectable.click(changeNumFilters);  
  9. //calculatehowmanyareinitiallychecked  
  10. changeNumFilters();  
  11. });  
  12.  
  13. varselectable;  
  14. functionchangeNumFilters()  
  15. {  
  16. //thisneedstobecheckedoneverycall  
  17. //sincethelengthcanchangewitheveryclick  
  18. varsize=$(":checked.selectable").length;  
  19. if(size>0)  
  20. $("#selectedCount").html(size);  
  21. else  
  22. $("#selectedCount").html("0");  
  23. }  
  24.  
  25. //handlestheselect/deselectofallcheckboxes  
  26. functionselectAll()  
  27. {  
  28. varchecked=$("#selectall").attr("checked");  
  29. selectable.each(function(){  
  30. varsubChecked=$(this).attr("checked");  
  31. if(subChecked!=checked)  
  32. {  
  33. $(this).click();  
  34. }  
  35. });  
  36. changeNumFilters();  
  37. }  

該代碼看起來比較簡單,因為我在好幾篇文章中都用到這個小部件。您在***篇文章中見到了“select/deselectall”小部件,我給出了它的基礎形式。在關于性能的文章中,您看到如何通過緩存選擇查詢和通過CLASS減少使用查詢來改進它的性能。但是還有一個問題需要解決。當在包含100行的表中勾選“select/deselectall”復選框之后,您將得到糟糕的性能。事實上,在我的瀏覽器中,如果使用了這些代碼,那么完成選擇的平均時間為3.4秒。響應性太差了!即使進行了各項優(yōu)化,仍然有些不可接受的地方。

讓我們深入一步考察這個算法,看看是否有地方出了問題。您將遍歷頁面上的每個復選框,看看它們當前的“checked”狀態(tài)是否與“select/deselectall”復選框一致。如果不一致,就對其調(diào)用“click”,以和“select/deselectall”復選框的狀態(tài)匹配。等一等,您還需要向這些復選框添加一個函數(shù),從而在每次單擊時都調(diào)用changeNumFilters()函數(shù)。

通過仔細檢查,您發(fā)現(xiàn)設置了一個可能調(diào)用changeNumFilters()101次的算法。怪不得性能如此差。很明顯,您不需要在每次單擊時都更新選中的消息的計數(shù),而是在該過程完成之后進行更新即可。在單擊復選框的同時如何才能避免調(diào)用該方法?

現(xiàn)在,unbind()方法開始發(fā)揮它的作用。通過在單擊復選框之前調(diào)用unbind(),將停止調(diào)用click(),同時避免了click()進一步調(diào)用changeNumFilter()方法。這很棒!現(xiàn)在就不會調(diào)用changeNumFilters()101次了。但是,這僅是一次有效的,在調(diào)用click方法之后,需要使用bind方法將click方法添加回到每個復選框。清單2顯示了更新之后的小部件。

  1. //handlestheselection/unselectionofallcheckboxes  
  2. functionselectAll()  
  3. {  
  4. varchecked=$("#selectall").attr("checked");  
  5. selectable.unbind("click",changeNumFilters);  
  6. selectable.each(function(){  
  7. varsubChecked=$(this).attr("checked");  
  8. if(subChecked!=checked)  
  9. {  
  10. $(this).click();  
  11. }  
  12. });  
  13. selectable.bind("click",changeNumFilters);  
  14. changeNumFilters();  

通過這些優(yōu)化之后,復選框的運行速度提高到約900毫秒,從而大大改進了性能。這些改進源于返回去檢查您的算法正在做什么,以及貫穿代碼的操作。您可以僅調(diào)用函數(shù)1次,而不是100次。通過在本系列的其他文章中不斷改進該函數(shù),您***會讓它變得更快、更高效。但不一定非得這么做,我還發(fā)現(xiàn)一個最快的算法,以前從來沒有透露過。此外,如果我過早地向您展示這個最快的算法,我就不能將其作為本文的題材了。希望它能使您看到在代碼中使用bind/unbind特性帶來的好處(如果沒有更好的方法的話)。

記住:在不希望觸發(fā)默認事件時才使用bind/unbind,或作為向頁面元素添加或刪除事件的臨時方法

清單3顯示了編寫該算法的最快方法(如果您的代碼中有這個小部件)。它運行該函數(shù)僅需40毫秒,遠遠勝過之前的其他方法。

  1. functionselectAll()  
  2. {  
  3. varchecked=$("#selectall").attr("checked");  
  4. selectable.each(function(){  
  5. $(this).attr("checked",checked);  
  6. });  
  7. changeNumFilters();  

#p#

Live/Die

jQuery 1.3版本的另外兩個強大的新特性是live()和die()函數(shù)。通過一個示例可以看到它對構建設計良好的Web應用程序的作用。想像一下對表中的每個單元格都添加一個雙擊。作為jQuery老手,您應該知道要在document.ready()函數(shù)中設置雙擊,如清單4所示。

  1. $("tr.messageRow").dblclick(function(){  
  2. if($(this).hasClass("mail_unread"))  
  3. {  
  4. $(this).removeClass("mail_unread");  
  5. }  
  6. }); 

這個設計存在一個問題。它向包含一個messageRow類的表的每行添加一個雙擊事件。但是,如果向該表添加新的行,會發(fā)生什么事情呢?例如,當您使用Ajax在未重新加載頁面的情況下將額外的消息加載到頁面時,可能會顯示這些行。這導致一個問題,因為所編寫的代碼不能工作。您創(chuàng)建的事件被綁定到所有在加載頁面時顯示的tr.messageRow元素中。

它沒有綁定到您在頁面的生命周期中創(chuàng)建的任何新的tr.messageRow中。編寫類似代碼的程序員最終會很失望的,因為它無法工作。在jQuery文檔發(fā)現(xiàn)該問題之前,jQuery新手可能要花好幾個小時才能弄明白為什么他們的代碼不能工作(這也是我去年的經(jīng)歷)。

在jQuery 1.3之前,有3種可以解決該問題的方法,但都不是很好(對于使用jQuery 1.2.x的程序員而言,它們?nèi)匀挥行В?**種方法是重新初始化技術,它在每次添加新的元素之后重新將事件添加到選中的元素中。第二種方法利用了bind/unbind,如前面小節(jié)所示。清單5顯示了這兩種方法。

  1. //firsttechniquetodealwith"hot"pageelements,addedduringthepage's  
  2. //lifetime  
  3. $("#mailtabletr#"+message.id).addClass("messageRow")  
  4. .dblclick(function(){  
  5. if($(this).hasClass("mail_unread"))  
  6. {  
  7. $(this).removeClass("mail_unread");  
  8. }  
  9.  
  10. //secondtechniquetodealwith"hot"pageelements  
  11. $("#mailtabletr#"+message.id).addClass("messageRow")  
  12. .bind("dblclick",(function(){  
  13. if($(this).hasClass("mail_unread"))  
  14. {  
  15. $(this).removeClass("mail_unread");  
  16. }  

這兩種方法都不是很好。您可能正在重復編寫代碼,或者被迫查找可能添加新頁面元素的點,然后在這些點上處理“熱元素”問題。這不是良好的編程方式。但是,jQuery可能大大簡化這一切,它能夠幫助我們完成很多事情。

幸運的是,有一個插件好像能夠解決該問題。這個插件稱為LiveQuery插件,它允許您將特定頁面元素綁定到事件,但僅能以“活動”的方式進行,因此所有頁面元素(包括創(chuàng)建頁面時自帶的元素和在頁面的生命周期中創(chuàng)建的元素)都可能觸發(fā)事件。對UI開發(fā)人員而言,這是一個非常智能、重要的插件,因為使得處理動態(tài)頁面就像處理靜態(tài)頁面一樣簡單。對于Web應用程序開發(fā)人員而言,它就是真正不可或缺的插件。

jQuery核心團隊意識到該插件的重要性,從而將其包含到1.3發(fā)布版中。這個“活動”特性現(xiàn)在是核心jQuery的一部分,因此任何開發(fā)人員都可以利用它。這個特性完整地包含在1.3核心代碼中,除了一小部分事件之外。我敢打賭,這些未被包含的事件將出現(xiàn)在jQuery的下一個發(fā)布版之中。我們看看如何利用它改變代碼。

  1. $("tr.messageRow").live("dblclick",function(){  
  2. if($(this).hasClass("mail_unread"))  
  3. {  
  4. $(this).removeClass("mail_unread");  

通過對代碼進行一處小更改,該頁面上的所有tr.messageRow元素被雙擊時都將觸發(fā)這段代碼。僅使用dblclick()函數(shù)是看不到這種行為的,如上所述。為此,我極力推薦您在大部分事件方法中使用live()方法。事實上,我認為它對于任何動態(tài)地創(chuàng)建頁面元素的頁面都是必不可少的,不管是通過Ajax還是用戶交互進行創(chuàng)建,都需要使用live()函數(shù)而不是事件方法。它很好的實現(xiàn)了易編寫和bug之間的折衷。

記住:當將事件添加到動態(tài)頁面元素時要使用live()方法。這讓事件和頁面元素一樣具有動態(tài)性。

#p#

Ajax Queue/Sync

在服務器中使用Ajax調(diào)用成為Web2.0公司度量自身的度量指標。我們已經(jīng)多次討論過,在jQuery中使用Ajax就像調(diào)用普通的方法一樣簡單。這意味著您可以輕松地調(diào)用任何服務器端Ajax函數(shù),就像調(diào)用客戶端的JavaScript函數(shù)一樣。但是美中存在一些不足之處,當對服務器進行過多的Ajax調(diào)用時,就會出現(xiàn)一些負面效應。如果Web應用程序使用的Ajax調(diào)用過多,就會導致問題。

***個問題是一些瀏覽器限制打開的服務器連接的數(shù)量。在Internet Explorer中,當前版本僅支持打開2個服務器連接。Firefox支持打開8個連接,但仍然是一個限制。如果Web應用程序不對Ajax調(diào)用進行控制,它就很可能打開2個以上的連接,尤其是服務器端調(diào)用屬于時間密集型調(diào)用時。這個問題可能源于Web應用程序的不良設計,或用戶不對請求加以限制。不管是那種情況都是不可取的,因為您不希望由瀏覽器決定使用哪些連接。

另外,因為調(diào)用是異步的,不能保證從服務器返回的響應的順序與發(fā)送時一樣。例如,如果您幾乎同時發(fā)出2個Ajax調(diào)用,您就不能保證服務器的響應是以相同的順序返回。因此,如果第二個調(diào)用依賴于***個調(diào)用的結果,那么就會出現(xiàn)問題。想象這樣一種場景,其中***個調(diào)用獲取數(shù)據(jù),第二個調(diào)用在客戶端操作該數(shù)據(jù)。如果第二個調(diào)用的響應返回得比***個Ajax調(diào)用快,那么您的代碼就會導致錯誤。您完全不能保證響應速度。當調(diào)用更多時,就更容易導致問題。

jQuery的創(chuàng)建者意識到這個潛在的問題,但同時也認識到它僅會給1%的Web應用程序帶來問題。但1%開發(fā)Web應用程序的開發(fā)人員需要一個解決辦法。因此創(chuàng)建了一個插件,通過創(chuàng)建一個Ajax Queue和一個Ajax Sync來篩查該問題。Queue和Sync的功能是很相似的:Queue一次發(fā)出一個Ajax調(diào)用,并且等待其響應返回之后才發(fā)出另一個調(diào)用。Sync幾乎同時發(fā)出多個調(diào)用,但調(diào)用的響應是按先后順序返回的。

通過在客戶端控制Ajax調(diào)用解決了超載問題,同時也控制和規(guī)范了將響應發(fā)送回客戶端的方式。現(xiàn)在,您可以確保知道響應返回到客戶端的順序,從而可以根據(jù)事件的順序編寫代碼。我們看看這個插件是如何工作的,以及如何在您的代碼中使用它(見清單7)。記住,這僅是為1%的Web應用程序設計的,它們擁有多個Ajax調(diào)用,并且后一個調(diào)用嚴重依賴于前一個調(diào)用的結果。這個示例不是調(diào)用相互依賴的例子,但它能夠向您展示如何使用該插件(要為這個插件的應用創(chuàng)建一個***的真實例子,并讓其易于理解是很困難的)。

  1. varnewRow="<trid='?'>"+  
  2. "<td><inputtypeinputtype=checkboxvalue='?'></td>"+  
  3. "<td>?</td>"+  
  4. "<td>?</td>"+  
  5. "<td>?</td>"+  
  6. "<td>?</td></tr>"; 

 

  1. $("#mailtable").everyTime(30000,"checkForMail",function(){  
  2. //byusingtheAjaxQueuehere,wecanbesurethatwewillcheckformail  
  3. //every30seconds,butONLYifthepreviousmailcheckhasalreadyreturned.  
  4. //Thisactuallywouldbebeneficialinamailapplication,ifonecheckfor  
  5. //newmailtakeslongerthan30secondstorespond,wewouldn'twantthe  
  6. //nextAjaxcalltokickoff,becauseitmightduplicatemessages(depending  
  7. //ontheserversidecode).  
  8. //So,byusingtheAjaxQueueplug-in,wecanensurethatourWebclient  
  9. //isonlycheckingfornewmailonce,andwillneveroverlapitself.  
  10.  
  11. $.ajaxQueue({  
  12. url:"check_for_mail.jsp",  
  13. success:function(data)  
  14. {  
  15. varmessage=eval('('+data+')');  
  16. if(message.id!=0)  
  17. {  
  18. varrow=newRow.replace("?",message.id);  
  19. rowrow=row.replace("?",message.id);  
  20. rowrow=row.replace("?",message.to);  
  21. rowrow=row.replace("?",message.from);  
  22. rowrow=row.replace("?",message.subject);  
  23. rowrow=row.replace("?",message.sentTime);  
  24. $("#mailtabletbody").prepend(row);  
  25. $("#mailtable#"+message.id).addClass("mail_unread").addClass("messageRow");  
  26. $("#mailtable#"+message.id+"td").addClass("mail");  
  27. $("#mailtable:checkbox").addClass("selectable");  
  28. }  
  29. }  
  30. });  

記住:如果您的應用程序有多個相互依賴的Ajax調(diào)用,那么要考慮使用Ajax Queue或Ajax Sync。

#p#

第二個示例Web應用程序

我將使用另一個小部件解決本文的***3個問題,并且在深入研究其代碼之前展示和解釋它。這個401k小部件并不陌生,因為您已經(jīng)在前面的文章見過它(參見參考資料部分獲取這些文章的鏈接)。不過,這回有個微妙的不同之處,因為我在同一個頁面上兩次添加了這個小部件。它被添加到兩個不同的表中。這將帶來幾個有趣的地方。圖3顯示了這個小部件:

第二個示例Web應用程序

在這個小部件中,我正在做幾件事情。***件是計算文本字段之和并確定它們是否為100。如果它們的和不為100,我將向用戶顯示一個錯誤,提示他們沒有正確使用該小部件。第二,我在每個選項獲取輸入之后對選項進行排序。通過這種方式,百分比***的投資分配將一直出現(xiàn)在表的頂部。這可以在圖3中看到,它按百分比對選項進行排序。***,為了讓它更酷,我添加了一些條帶。

用于生產(chǎn)這個小部件的HTML代碼出奇地簡單。清單8詳細地顯示了這個小部件。

  1. <p><tablewidthtablewidth=300class="percentSort"cellpadding=0cellspacing=0> 
  2. <tbody> 
  3. <tr><td>S&P500Index</td> 
  4. <td><inputtypeinputtype=text>%</td></tr> 
  5. <tr><td>Russell2000Index</td> 
  6. <td><inputtypeinputtype=text>%</td></tr> 
  7. <tr><td>MSCIInternationalIndex</td> 
  8. <td><inputtypeinputtype=text>%</td></tr> 
  9. <tr><td>MSCIEmergingMarketIndex</td> 
  10. <td><inputtypeinputtype=text>%</td></tr> 
  11. <tr><td>REITIndex</td> 
  12. <td><inputtypeinputtype=text>%</td></tr> 
  13. </tbody> 
  14. <tfoot> 
  15. </tfoot> 
  16. </table> 

用jQuery設置小部件

以上的一小段HTML直接引入了這部分內(nèi)容,本小節(jié)關注如何在jQuery中設置小部件,以及所需的所有代碼。要將事件附加到頁面元素或在特定情況下需要添加類時,通常需要這樣做。有時候還需要更進一步。這些小部件的所有設置代碼都是jQuery代碼。

我可以提供關于角色分離的理論,讓HTML設計師和JavaScript程序員各自完成自己的工作,但是您們可能已經(jīng)多次聽到這種陳詞。在這里我僅添加另一樣東西,即“類修飾”,這是很多插件創(chuàng)作者都使用的。看看清單8中的HTML代碼,僅通過將一個percentSort類添加到表,您就可以顯著改變表的功能和外觀。這是小部件設計的目標,讓添加和刪除小部件就像向小部件添加類一樣簡單。

讓我們遵循我曾用jQuery設置小部件的幾個步驟。通過查看這些步驟,您可以看到清單9中的設計模式是如何出現(xiàn)的。

  1. $(document).ready(function(){  
  2.  
  3. //thefirststepistofindallthetablesonthepagewith  
  4. //aclassofpercentSort.Theseareallthetableswewantto  
  5. //convertintoourwidget.  
  6. //Afterwefindthem,weneedtoloopthroughthemandtakesome  
  7. //actionsonthem  
  8. //Attheconclusionofthisblockofcode,eachtablethat'sgoingto  
  9. //beapercentSortwidgetwillhavebeentransformed  
  10.  
  11. $("table.percentSort").each(function(i){  
  12.  
  13. //eachtableneedsauniqueID,fornamespaceissues(discussedlater)  
  14. //wecansimplycreateauniqueIDfromtheloopcounter  
  15.  
  16. $(this).attr("id","percentSort-"+i);  
  17.  
  18. //withineachtable,let'shighlighteveryotherrowinthetable,to  
  19. //giveitthat"zebra"look  
  20.  
  21. $(this).find("tbody>tr").filter(":odd").addClass("highlight");  
  22.  
  23. //becauseeachtableneedstoshowthe"Total"totheuser,let'screateanew  
  24. //sectionofthetableinthefooter.We'lladdarowinthetablefooter  
  25. //todisplaythewords"Total"andaspanfortheupdatedcount.  
  26.  
  27. $("#"+$(this).attr("id")+"tfoot")  
  28. .append("<tr><td>Total</td><td> 
  29. <span></span>%</td></tr>");  
  30.  
  31. //finally,let'saddtheCLASSof"percentTotal"tothespanwejust  
  32. //createdabove.We'llusethisinformationlatertodisplay  
  33. //theupdatedtotals  
  34.  
  35. $("#"+$(this).attr("id")+"tfootspan").addClass("percentTotal");  
  36. });  
  37.  
  38. //nowthesecondstep,afterwe'vecompletedsettingupthetablesthemselves  
  39. //istosetuptheindividualtablerows.  
  40. //Wecansimilarlysortthrougheachofthem,takingtheappropriateactions  
  41. //oneachoftheminturn.  
  42. //Uponcompletionofthisblockofcode,eachrowineachtablewillbe  
  43. //transformedforourwidget  
  1. $("table.percentSorttbody>tr").each(function(i){  
  2.  
  3. //getthenamespace(tobediscussedinthenextsection)  
  4.  
  5. varNAMESPACE=$(this).parents("table.percentSort").attr("id");  
  6.  
  7. //attachauniqueIDtothisrow.Wecanusetheloopcounter  
  8. //toensuretheIDisuniqueonthepage(whichisamustoneverypage)  
  9.  
  10. $(this).attr("id","row"+i);  
  11.  
  12. //now,withinthisrowofthetable,weneedtofindthetextinput,because  
  13. //weneedtoattachaclasstothem.Weutilizethenamespace,andalso  
  14. //findthe:textwithinthetablerow,andthenattachthecorrectclass  
  15.  
  16. $("#"+$(this).attr("id")+":text").addClass("percent");  
  17.  
  18. //Finally,weattachauniqueIDtoeachofthetextinputs,andwedothisby  
  19. //makingitacombinationofthetablenameandtherowname.  
  20.  
  21. $("#"+$(this).attr("id")+".percent").  
  22. attr("id",NAMESPACE+"-"+$(this).attr("id"));  
  23. });  
  24. //Finally,becauseweknowweonlywantnumericalinputs,werestrictthetextentry  
  25. //tojustnumbers.Wemustdothisnow,becauseupuntilthispoint,thepage  
  26. //containednoelementswiththeCLASS"percent"  
  27. $(".percent").numeric();  

如您從這個例子中見到的一樣,可以通過jQuery代碼向HTML代碼引入大量功能。這種類型的設計的好處是很明顯的。同樣,遵循角色分離、代碼重用等也是非常有益的。您還將在小部件插件中看到這種類型的設計,因為它將簡單的HTML代碼轉(zhuǎn)變成適用于插件的小部件。最重要的是,這也是您在這里需要完成的任務,即編寫一個插件來將一個簡單的表轉(zhuǎn)變成排序和匯總表。

記住:盡量多使用jQuery代碼進行設置,并且盡可能少使用HTML。

#p#

名稱空間

可能處理這種類型的設計和jQuery的最難解方面是理解名稱空間。這個例子很好,因為它以一種很直觀的方式展示了該問題。知道頁面上的所有ID和類時,編寫jQuery代碼是非常簡單的。這就是jQuery的設計目標。當您不知道頁面上有幾個類時,或這些類開始重復時,會發(fā)生什么呢?在這個例子中,您可以直接看到問題,有兩個完全相同的小部件!所有東西都是重復的。這似乎是不考慮名稱空間引起的問題;您的小部件開始彼此干擾,最終導致不能正常工作。

名稱空間

造成這個問題的原因是您僅調(diào)用$(".percentTotal")等,而忽略了應該同步哪個小部件。因為相同的頁面上有多個表,因此該頁面就有percentTotal類的多個實例。當然,如果頁面上僅有一個表,那么您就可以確定它是唯一的。但是隨著頁面更加高級,以及組件的重用越來越多,這種一個表的假設就不再成立。有些人會問,“在這里使用ID不行嗎?”這不能解決問題:您打算給它什么ID?您不可以使用“percentTotal”,因為這會帶來歧義。

也不可以使用“percentTotal-1”,因為它不表示頁面上的任何東西。(以上數(shù)字畢竟是任意創(chuàng)建的)。您可以向頁面包含的表添加一些引用來解決問題,比如“percentTotal-percentSort1”,但這會讓問題更加復雜。jQuery有一個超級復雜但又十分容易使用的選擇語法,從而讓這種混合命名模式變得毫無必要。為什么要重新創(chuàng)造已有的東西呢?讓我們使用jQuery的選擇引擎幫助您解決名稱空間問題。

這個小部件的核心問題是決定操作發(fā)生在哪個小部件中。當向文本框輸入數(shù)字時,您可以問自己,jQuery如何知道進入哪個文本框?您在代碼中的“百分比”類添加了一個事件,并且可以在代碼內(nèi)部使用$(this)引用它。這將我們帶入下一個問題:jQuery如何知道問題發(fā)生在哪個小部件中,從而使您能夠更新正確的percentTotal字段?我認為這不是一件簡單的事情。這確實不簡單。盡管您的代碼能夠向頁面上帶有“百分比”類的每個文本框添加一個事件,但如果忽略了發(fā)生事件的小部件就是不妥當?shù)摹?/p>

這個問題被歸結為名稱空間問題的原因是,小部件的命名不清晰,容易導致問題。要使jQuery代碼正常工作,每個名稱都必須在其自己的空間之內(nèi)明確定義,這就出現(xiàn)了術語名稱空間。您必須避免編寫重名的代碼,實現(xiàn)每個小部件都是自含的。您必須能夠在相同的頁面上添加相同小部件的多個實例,同時避免名稱重復。最重要的是,每個小部件在頁面上都是獨立的。

沒有能夠處理名稱空間問題的現(xiàn)成方法,因此我將展示我的解決辦法,您可以在自己的代碼中使用我的辦法,或通過了解問題創(chuàng)建更好的解決辦法。我喜歡該代碼的原因是它簡單易用(只有1行),并且能夠讓您在某種程度上控制自己的名稱空間。看看清單10。

  1. //oureventisattachedtoEVERYinputtextfieldwithaCLASSof"percent"  
  2. //thismakesourcodelookgood,butcanleadtonamespaceissues  
  3. $("table.percentSortinput.percent").keyup(function(){  
  4.  
  5. //thissimplelinecanestablishanamespaceforus,bygettingtheunique  
  6. //IDattachedtoourtable(thetableisconsideredthe"container"for  
  7. //ourwidget.Itcouldbeanything,dependingonyourspecificcode.)  
  8. //WepasstheCLASSofourwidgettotheparents()function,because  
  9. //thateffectivelyencapsulatesthewidget  
  10.  
  11. varNAMESPACE="#"+$(this).parents("table.percentSort").attr("id");  
  12.  
  13. //withthenamespaceestablished,wecanusethejQueryselection  
  14. //syntaxtousethisnamespaceasourprefixforallofourremaining  
  15. //searches.Noticehowtheambiguityisremovedforoursearch  
  16. //byCLASSof"percent"and"percentTotal"  
  17. //Thissolvesournamespaceissues  
  18.  
  19. varsum=$(NAMESPACE+"input.percent").sum();  
  20. vartotalField=$(NAMESPACE+".percentTotal"); 

因此,僅需添加一行代碼,您就能夠封裝小部件,從而避免它的函數(shù)與自身的其他實例重復(或者甚至是其他碰巧對ID或類使用相同名稱的小部件)。這種類型的代碼編寫方式在插件代碼中很常見。編寫良好的插件應該考慮到名稱空間問題,而糟糕的插件忽略了這個問題。從這個例子中可以看到,在代碼中使用名稱空間也是很簡單的,并且隨著頁面越來越復雜,它可以給您節(jié)省大量時間。鑒于這個原因,我建議您現(xiàn)在就開始考慮jQuery代碼中的名稱空間問題,并在編寫代碼時使用這種解決辦法。

記住:開始編寫jQuery代碼時,一般就要開始包含名稱空間解決辦法。您可以使用以上的解決辦法,或創(chuàng)建自己的解決辦法。通過采用名稱空間解決辦法,即使代碼越來越復雜,也不會帶來名稱重復問題。

#p#

結束語

本文提供一些技巧,幫助您將良好的jQuery代碼轉(zhuǎn)變成強大的jQuery代碼。jQuery非常簡單易用(并且是獨立的JavaScript的巨大改進),因此編寫良好的jQuery代碼也很容易。大部分開發(fā)人員在幾分鐘之內(nèi)編寫完并運行良好的jQuery代碼。但是良好的代碼和強大的代碼是有區(qū)別的。強大的jQuery代碼考慮隨著頁面越來越復雜時的性能問題。強大的jQuery代碼能夠考慮到頁面的未來方向,而不是僅看到當前的位置。強大的jQuery代碼是為最復雜的應用程序設計的,然后讓應用程序處理輸入的簡單信息。

本文介紹了5個概念,幫助您將良好的jQuery代碼轉(zhuǎn)變成強大的jQuery代碼。

***個概念是使用bind()/unbind()方法。當您不希望在頁面的生命周期內(nèi)將事件添加到代碼時,這些方法對向頁面元素添加/移除事件非常有用。這些方法在頁面包含大量事件時對提升性能非常重要,或者用于某些用戶界面中。

第二個概念是使用1.3中包含的新特性live()/die()。這些函數(shù)允許將事件變成動態(tài)的,就像頁面元素一樣。隨著Web應用程序包含的頁面元素越來越多,這些函數(shù)允許代碼隨著頁面的增長而增長,這在以前的發(fā)布版中是無法實現(xiàn)的。您希望事件處理像頁面處理一樣具有動態(tài)性。

第三個新添加的特性是AjaxQueue/Sync插件,它用于規(guī)范和控制對服務器發(fā)出的Ajax調(diào)用,避免它們超出限度(從客戶端角度看)。當Ajax調(diào)用的響應返回順序很重要時,該插件也能幫上大忙。

第四個概念是,盡可能多地用jQuery代碼編寫頁面設置代碼。這讓HTML的編寫更加簡單,并且在設置頁面時能夠獲得更多的控制。

***一個概念是,在代碼中利用名稱空間解決辦法,避免因小部件的函數(shù)名稱重復而導致問題。每個頁面元素和小部件都應該是自含的,不與頁面的其他方面發(fā)生干擾,名稱空間解決辦法能夠阻止該問題。

這5個步驟并不難實現(xiàn)。事實上,其中4個步驟僅需修改一行代碼。不過,理解如何在代碼中應用它們才是最重要的。像所有東西一樣,如果不能正確時使用,它不僅不能提供幫助,反而還有害處。我的建議是,當您用jQuery代碼編寫頁面時,要盡快應用這5個步驟。每個開發(fā)人員都會告訴您,利用特性是編程過程的一部分。您不希望僅因開頭設計得不好或更改某些部分而重新設計整個Web應用程序。編寫代碼時就要抱有編寫強大應用程序的想法,并且遵循這些建議。

【編輯推薦】

  1. jQuery四大天王:核心函數(shù)詳解
  2. 拋磚引玉 自定義jQuery擴展接口
  3. 改變獲取對象方式 ***的jQuery選擇器
  4. 使用jQuery構建未來Web應用程序
  5. jQuery另類視角:動態(tài)擴展對象
責任編輯:王曉東 來源: IBM DW
相關推薦

2010-06-13 09:22:37

jQuery

2012-06-15 11:32:19

ibmdw

2019-10-17 10:10:23

優(yōu)化Web前端

2009-04-01 14:33:33

2009-07-09 16:47:26

Servlet的Web

2011-07-08 15:27:03

jQuery Mobi

2010-05-20 09:48:36

2011-03-22 14:12:17

LAMP

2009-12-21 09:54:54

Web應用程序安全測試

2013-06-24 10:21:47

面向?qū)ο?/a>Web應用JavaScript

2009-06-23 14:12:00

javaJSP絕招

2010-08-12 21:20:45

2012-04-19 09:34:21

ibmdw

2009-01-16 09:22:40

Web應用程序Web程序管理Web服務

2009-02-27 17:00:25

2013-11-19 15:35:01

2010-03-09 13:27:23

Web 2.0應用程序

2023-01-09 17:04:24

2010-02-01 14:05:03

2012-03-20 09:20:40

Go語言
點贊
收藏

51CTO技術棧公眾號

欧美俄罗斯乱妇| 亚洲第一成人在线| 成人在线小视频| 青青操国产视频| 婷婷亚洲成人| 欧美日韩精品一区二区三区蜜桃 | 在线观看免费高清视频| 欧美一区精品| 亚洲精品中文字幕av| 亚洲国产日韩欧美在线观看| caoporm免费视频在线| 99久久精品一区| 国产精品情侣自拍| xxxxxx国产| 黄色污在线观看| 国产原创中文av| 国产亚洲亚洲| 久久国产精品电影| 男生裸体视频网站| 国产精品日韩精品在线播放| 五月综合激情日本mⅴ| 亚洲精品久久区二区三区蜜桃臀| 亚洲成人一级片| 欧美aaaaaa午夜精品| 久久久在线视频| 长河落日免费高清观看| 色橹橹欧美在线观看视频高清| 欧美网站大全在线观看| 国产成人无码a区在线观看视频| jizz在线观看中文| 97成人超碰视| 91视频免费进入| 天天天天天天天干| 亚洲欧美成人| 久久久噜噜噜久久久| 99热6这里只有精品| 欧美精品第一区| 精品成人一区二区三区| 久久人人爽人人片| 欧美黑粗硬大| 欧美色图片你懂的| 熟女人妇 成熟妇女系列视频| 国内老司机av在线| 亚洲伦理在线精品| 黄频视频在线观看| 成人高清免费观看mv| 久久婷婷久久一区二区三区| 国产精品一区免费观看| www.久久色| 国产福利不卡视频| 亚洲一区二区中文| 97人妻一区二区精品免费视频| 奇米777欧美一区二区| 国产成人亚洲综合青青| 中文字幕一区在线播放| 一本久道久久综合婷婷鲸鱼| 久久久久久久国产| 日本网站免费观看| 国产精品毛片| 青草青草久热精品视频在线观看| 久久草视频在线| 午夜亚洲性色福利视频| 日韩女优人人人人射在线视频| 国产无人区码熟妇毛片多| 国产日韩亚洲欧美精品| 热门国产精品亚洲第一区在线| av资源免费观看| 日韩国产在线一| 国产精品人成电影| 国产免费福利视频| 成人综合婷婷国产精品久久| 国产精品有限公司| 青青青免费视频在线2| 国产午夜精品一区二区| 在线视频欧美一区| 欧美人与禽猛交乱配| 五月天婷婷综合| 成人3d动漫一区二区三区| 国产精品xxx| 日韩免费视频一区二区| 国产性生活毛片| 精品国产一区二区三区四区| 夜夜嗨av色综合久久久综合网| 亚洲av成人无码久久精品| 教室别恋欧美无删减版| 久久精品福利视频| 深夜福利影院在线观看| 国产一区视频在线观看免费| 午夜精品久久久久久久男人的天堂 | 视频一区二区视频| a级在线观看| 亚洲一区二区中文在线| 久久久久久久午夜| 韩日精品一区| 欧美一激情一区二区三区| 女人扒开双腿让男人捅| 国产女人18毛片水真多18精品| 欧美一区二区私人影院日本| 一级欧美一级日韩片| 国产91精品对白在线播放| 日韩中文字幕在线播放| 国产67194| 日韩视频二区| 国产精品黄页免费高清在线观看| 国产精品久久影视| av不卡在线播放| 色播亚洲婷婷| 日韩精品亚洲人成在线观看| 色菇凉天天综合网| 欧美性受xxxx黒人xyx性爽| 白嫩白嫩国产精品| 国产一区二区精品丝袜| 欧美精品久久久久性色| 乱人伦精品视频在线观看| 国产精品自在线| 亚洲精品无码专区| 久久久噜噜噜久久中文字幕色伊伊| 色噜噜狠狠色综合网| 日本视频不卡| 亚洲va欧美va人人爽| 国产精品99久久免费黑人人妻| 欧美黄页在线免费观看| 亚洲福利精品在线| 手机av在线不卡| 亚洲高清二区| 国产精品91视频| 亚洲av色香蕉一区二区三区| 国产亚洲精品aa午夜观看| 日韩精品综合在线| 欧美aaaaaaaa| 亚洲国产精品va在线看黑人 | 中文字幕综合网| 久草青青在线观看| 99亚洲乱人伦aⅴ精品| 一区二区三区无码高清视频| 国产精品成人久久| 男男视频亚洲欧美| 欧美欧美一区二区| 免费网站在线观看人| 欧美日韩视频在线观看一区二区三区 | 亚洲一区二区三区蜜桃| 国产真实久久| 成人激情免费在线| 国产51人人成人人人人爽色哟哟| 亚洲午夜免费电影| 久久久久亚洲av片无码v| 欧美在线色图| 青草青草久热精品视频在线网站 | 日韩电影在线免费| 欧美13一14另类| 国模精品视频| 日韩久久久久久| 妺妺窝人体色www聚色窝仙踪| 久久国产精品免费| 亚洲精品在线观看免费| 日韩制服一区| 一本一本久久a久久精品牛牛影视| 国产精品老女人| 99久久精品免费看国产免费软件| 国产 国语对白 露脸 | 欧美视频精品在线| 91精品人妻一区二区三区| 国产精品呻吟| 久久久久久久久一区二区| wwww在线观看免费视频| 日韩女优av电影| 国产一级二级三级| 国产福利精品一区| 青春草在线视频免费观看| 高清国产一区二区三区四区五区| 日韩综合视频在线观看| 亚洲自拍一区在线观看| 久久香蕉国产线看观看99| 午夜肉伦伦影院| 一区二区三区视频免费观看| 欧美一区在线直播| 精品成人一区二区三区免费视频| 日本久久一区二区三区| 刘亦菲国产毛片bd| 国产精品一区在线观看乱码| 欧美人与动牲交xxxxbbbb| 香蕉大人久久国产成人av| 久久91精品国产91久久久| 精品久久久无码中文字幕| 亚洲一区二区三区免费视频| 亚洲一级Av无码毛片久久精品| 亚洲乱码视频| 你懂的视频在线一区二区| 日韩欧乱色一区二区三区在线 | 精品成人一区| 久久婷婷人人澡人人喊人人爽| 亚洲精品mv| 中文日韩在线观看| 国产手机视频在线| 亚洲狠狠爱一区二区三区| 女尊高h男高潮呻吟| 丝瓜av网站精品一区二区| 国产奶头好大揉着好爽视频| 成功精品影院| 国产精品久久久久久久久久久久久| av黄色在线观看| 日韩一区二区三区电影在线观看 | 2019最新中文字幕| 国产黄色片在线播放| 欧美一区在线视频| 91精品国产乱码在线观看| 久久久www成人免费毛片麻豆| 福利片一区二区三区| 国色天香一区二区| 婷婷五月色综合| 日韩精品一区二区三区免费视频| 91精品国产色综合久久不卡98| 不卡在线视频| 精品国偷自产国产一区| 一级黄色片视频| 天天综合色天天综合| 亚洲女优在线观看| 国产电影精品久久禁18| 欧美视频免费播放| 亚洲激情五月| 奇米影视首页 狠狠色丁香婷婷久久综合 | 中国china体内裑精亚洲片| 高清毛片aaaaaaaaa片| 欧美性生交大片免费| 国产美女久久久久久| 91网上在线视频| 欧美视频亚洲图片| 蜜桃视频一区| 国产一二三在线视频| 日韩欧美网站| 欧美久久久久久一卡四| 欧美黄页在线免费观看| 国产精欧美一区二区三区| av不卡高清| 久久夜色精品国产欧美乱| 男人天堂网在线| 精品久久久久久无| 国产精品一二三四五区| 欧美性猛交xxxx偷拍洗澡| 久久国产露脸精品国产| 亚洲永久精品国产| 亚洲色偷偷综合亚洲av伊人| 国产日韩视频一区二区三区| 国产精品久久久久久亚洲色 | 国产欧美第一页| 一本大道综合伊人精品热热 | av影片在线一区| 日韩精品欧美专区| 亚洲日本三级| 精品国产一区二区三区四区精华| 日韩成人久久| 91久久国产综合久久91精品网站 | 国产欧美精品va在线观看| 久久久久毛片| 国产精品成人va在线观看| 深夜福利视频一区二区| 97超级碰碰碰久久久| 国产伦理精品| 久久久久久中文| 国模精品视频| 欧美在线免费视频| 午夜影院在线播放| 欧美中文字幕第一页| 色在线中文字幕| 欧美在线视频免费| 亚洲妇女成熟| 国产97在线亚洲| 日韩一区二区三区在线免费观看| 国产精品黄色影片导航在线观看| 国产成人免费| 国产女精品视频网站免费| 中文.日本.精品| 国产成人精品视频| 欧美日韩尤物久久| 成人h视频在线| 电影一区中文字幕| 粉嫩高清一区二区三区精品视频| av一级亚洲| 欧美国产一二三区| 欧美一级本道电影免费专区| 偷拍视频一区二区| 图片区亚洲欧美小说区| 成人在线观看毛片| 激情欧美丁香| 精品无码一区二区三区爱欲| 亚洲一区国产一区| 日本激情视频在线播放| 精品一区二区久久久| 久久aaaa片一区二区| 成人精品鲁一区一区二区| 亚洲av无码国产精品久久| 国产精品乱人伦一区二区| 欧美激情图片小说| 亚洲成人一区二区| 国产91精品看黄网站在线观看| 欧美日韩综合色| www夜片内射视频日韩精品成人| 欧美一区二区网站| 国产一二在线观看| 成人444kkkk在线观看| 色戒汤唯在线观看| 成人在线中文字幕| 欧美尿孔扩张虐视频| 亚洲二区自拍| 99在线|亚洲一区二区| the porn av| 成人av影院在线| 黄大色黄女片18免费| 亚洲一级二级三级在线免费观看| 黄色在线免费观看| 亚洲护士老师的毛茸茸最新章节| 国产三级电影在线观看| 欧美精品一二区| 粉嫩一区二区| 91系列在线播放| 精品在线播放| 国精产品一区一区三区视频| 日本午夜一区二区| 少妇被狂c下部羞羞漫画| 国产精品美女久久久久av爽李琼| 国产无遮挡免费视频| 欧美午夜寂寞影院| 国产高清免费观看| 久久综合伊人77777蜜臀| 日韩成人亚洲| 国产一区不卡在线观看| 一本到12不卡视频在线dvd| 久久精品免费一区二区| 国产一区二区三区美女| 国产一区二区三区视频播放| 福利视频一区二区| 亚洲高清在线观看视频| 久久久精品久久久| 视频精品导航| 婷婷久久五月天| 老司机精品导航| 强迫凌虐淫辱の牝奴在线观看| 亚洲视频一二三| 中文字幕在线观看免费| 欧美tickling网站挠脚心| 超碰在线caoporn| 国产精品美腿一区在线看| 美女一区2区| 九九热只有这里有精品| 国产成人啪午夜精品网站男同| 日韩中文字幕电影| 日韩欧美在线视频日韩欧美在线视频 | 黄色在线视频观看网站| 51视频国产精品一区二区| 中文字幕一区二区三区中文字幕 | 日韩 欧美 视频| 国产伦精品一区二区三区视频青涩| 三区四区在线观看| 欧美自拍丝袜亚洲| 激情小视频在线观看| 97视频免费在线观看| 日本成人a网站| 日韩精品―中文字幕| 99re热视频精品| 日韩少妇高潮抽搐| 精品国产乱码久久久久久夜甘婷婷| 牛牛电影国产一区二区| 国产日韩欧美综合精品| 伊人影院久久| 噜噜噜在线视频| 欧美小视频在线| 四虎精品成人免费网站| 国产精品久久在线观看| 欧美黄色录像片| 亚洲免费黄色网| 亚洲另类一区二区| 亚洲国产视频一区二区三区| 午夜精品三级视频福利| 自拍亚洲一区| 精品久久久久久久无码 | 欧美私人免费视频| 永久免费av在线| 2019国产精品视频| 亚洲国产国产亚洲一二三| 手机在线看片日韩| 欧洲一区在线观看| 麻豆网在线观看| 国产一区二区高清不卡| 三级亚洲高清视频| 我要看黄色一级片| 欧美精品一区视频| 国产白浆在线免费观看| 日韩欧美亚洲在线| 国产乱淫av一区二区三区 | 99成人在线视频| 一卡二卡三卡四卡五卡| 亚洲成人动漫一区| 国产小视频免费在线网址| 国产成+人+综合+亚洲欧美丁香花| 亚洲午夜精品一区 二区 三区| 久久久国产精品久久久| 欧美视频在线看| av资源网站在线观看| caoporen国产精品| 日本成人在线一区|