提高您技能的 14 個 jQuery 技巧、提醒和最佳實踐

提高您技能的 14 個 jQuery 技巧、提醒和最佳實踐

如果說 jQuery 有一點的話,那就是它的入門水平低得驚人,以至于它往往會吸引那些對 JavaScript 沒有一點了解的人。現在,一方面,這太棒了。然而,另一方面,它也會導致一些,坦率地說,令人厭惡的糟糕代碼(其中一些是我自己編寫的!)。

不過沒關系;糟糕得可怕的代碼甚至會讓你的祖母喘不過氣來,這是一種成人儀式。關鍵是要翻過山,這就是我們今天教程中要討論的內容。


1。 方法返回 jQuery 對象

請務必記住,大多數方法都會返回 jQuery 對象。這非常有用,并且允許我們經常使用的鏈接功能。

 $someDiv   .attr('class', 'someClass')   .hide()   .html('new stuff'); 

知道 jQuery 對象總是被返回,我們有時可以使用它來刪除多余的代碼。例如,考慮以下代碼:

 var someDiv = $('#someDiv'); someDiv.hide(); 

我們之所以“緩存” someDiv 元素的位置,是為了將我們必須遍歷該元素的 DOM 的次數限制為一次。

上面的代碼完全沒問題;但是,您可以輕松地將兩條線合并為一條線,同時獲得相同的結果。

 var someDiv = $('#someDiv').hide(); 

這樣,我們仍然隱藏 someDiv 元素,但正如我們所知,該方法也返回 jQuery 對象——然后通過 someDiv 變量引用該對象。


2。 查找選擇器

只要你的選擇器不是糟糕得離譜,jQuery 就會盡可能地優化它們,而且你通常不需要太擔心它們。不過,話雖如此,您可以進行一些改進,從而稍微提高腳本的性能。

一種這樣的解決方案是在可能的情況下使用 find() 方法。如果沒有必要的話,關鍵是不要強迫 jQuery 使用它的 Sizzle 引擎。當然,有時這是不可能的——但這沒關系;但是,如果您不需要額外的開銷,就不要尋找它。

 // Fine in modern browsers, though Sizzle does begin "running" $('#someDiv p.someClass').hide();  // Better for all browsers, and Sizzle never inits. $('#someDiv').find('p.someClass').hide(); 

最新的現代瀏覽器支持 QuerySelectorAll,它允許您傳遞類似 CSS 的選擇器,而不需要 jQuery。 jQuery 本身也會檢查此函數。

但是,較舊的瀏覽器(即 IE6/IE7)不提供支持,這是可以理解的。這意味著這些更復雜的選擇器會觸發 jQuery 的完整 Sizzle 引擎,該引擎雖然很出色,但確實會帶來更多的開銷。

Sizzle 是一大堆我可能永遠無法理解的精彩代碼。然而,在一句話中,它首先將您的選擇器變成一個由選擇器的每個組件組成的“數組”。

 // Rough idea of how it works  ['#someDiv, 'p']; 

然后,從右到左,開始使用正則表達式破譯每個項目。這也意味著選擇器的最右側部分應盡可能具體 – 例如,id 或標記名稱。

底線,如果可能的話:

  • 保持選擇器簡單
  • 利用 find() 方法。這樣,我們就可以繼續使用瀏覽器的原生功能,而不是使用 Sizzle。
  • 使用 Sizzle 時,盡可能優化選擇器的最右側部分。

上下文?

還可以向選擇器添加上下文,例如:

 $('.someElements', '#someContainer').hide(); 

此代碼指示 jQuery 在 jQuery 中使用 someElements 類(它們是 someContainer 的子級)包裝所有元素的集合。使用上下文是限制 DOM 遍歷的一種有用方法,但在幕后,jQuery 使用 find 方法來代替。

 $('#someContainer')   .find('.someElements')   .hide(); 

證明

 // HANDLE: $(expr, context) // (which is just equivalent to: $(context).find(expr) } else {    return jQuery( context ).find( selector ); } 

3。 不要濫用$(this)

在不了解各種 DOM 屬性和功能的情況下,很容易不必要地濫用 jQuery 對象。例如:

 $('#someAnchor').click(function() { 	// Bleh 	alert( $(this).attr('id') ); }); 

如果我們對 jQuery 對象的唯一需要是訪問錨標記的 id 屬性,那么這是浪費的。最好堅持使用“原始”JavaScript。

 $('#someAnchor').click(function() { 	alert( this.id ); }); 

請注意,應該始終通過 jQuery 訪問三個屬性:“src”、“href”和“style”。這些屬性需要在舊版本的 IE 中使用 getAttribute。

證明

 // jQuery Source var rspecialurl = /href|src|style/; // ...  var special = rspecialurl.test( name ); // ... var attr = !jQuery.support.hrefNormalized && notxml && special ? 	// Some attributes require a special call on IE 	elem.getAttribute( name, 2 ) : 	elem.getAttribute( name ); 

多個 jQuery 對象

更糟糕的是重復查詢 DOM 和創建多個 jQuery 對象的過程。

 	$('#elem').hide(); 	$('#elem').html('bla'); 	$('#elem').otherStuff(); 

希望您已經意識到這段代碼的效率有多低。如果沒有,也沒關系;我們都在學習。答案是要么實現鏈接,要么“緩存” #elem 的位置。

 	// This works better 	$('#elem') 	  .hide() 	  .html('bla') 	  .otherStuff();  	// Or this, if you prefer for some reason. 	var elem = $('#elem'); 	elem.hide(); 	elem.html('bla'); 	elem.otherStuff(); 

4。 jQuery的簡寫Ready方法

使用 jQuery 監聽文檔何時準備好進行操作是非常簡單的。

 $(document).ready(function() { 	// let's get up in heeya }); 

不過,您很可能遇到過不同的、更令人困惑的包裝函數。

 $(function() { 	// let's get up in heeya }); 

盡管后者的可讀性稍差,但上面的兩個片段是相同的。不相信我?只需檢查 jQuery 源代碼即可。

 // HANDLE: $(function) // Shortcut for document ready if ( jQuery.isFunction( selector ) ) { 	return rootjQuery.ready( selector ); } 

rootjQuery 只是對根 jQuery(document) 的引用。當您將選擇器傳遞給 jQuery 函數時,它將確定您傳遞的選擇器類型:字符串、標記、id、函數等。如果傳遞了函數,jQuery 將調用其 ready() 方法,并將您的匿名函數作為選擇器傳遞。


5。 保證代碼安全

如果開發用于分發的代碼,補償任何可能的名稱沖突始終很重要。如果在您的腳本之后導入的某些腳本也具有 $ 函數,會發生什么情況?壞東西!

答案是要么調用 jQuery 的 noConflict(),要么將代碼存儲在自調用匿名函數中,然后將 jQuery 傳遞給它。

方法一:無沖突

 var j = jQuery.noConflict(); // Now, instead of $, we use j.  j('#someDiv').hide();  // The line below will reference some other library's $ function. $('someDiv').style.display = 'none'; 

請小心使用此方法,并在分發代碼時盡量不要使用它。這真的會讓腳本的用戶感到困惑! ??

方法二:傳遞jQuery

 (function($) { 	// Within this function, $ will always refer to jQuery })(jQuery); 

底部的最后一個括號自動調用該函數 – function(){}()。然而,當我們調用該函數時,我們還傳遞了 jQuery,然后用 $ 表示。

方法3:通過Ready方法傳遞$

 jQuery(document).ready(function($) {  // $ refers to jQuery });  // $ is either undefined, or refers to some other library's function. 

6。 要聰明

請記住 – jQuery 只是 JavaScript。不要假設它有能力彌補你的錯誤編碼。 ??

這意味著,正如我們必須優化 JavaScript for 語句等內容一樣,jQuery 的 each 方法也是如此。我們為什么不呢?它只是一個輔助方法,然后在幕后創建 for 語句。

 // jQuery's each method source 	each: function( object, callback, args ) { 		var name, i = 0, 			length = object.length, 			isObj = length === undefined || jQuery.isFunction(object);  		if ( args ) { 			if ( isObj ) { 				for ( name in object ) { 					if ( callback.apply( object[ name ], args ) === false ) { 						break; 					} 				} 			} else { 				for ( ; i  <h4> 太糟糕了 </h4> <pre class="brush:javascript;toolbal:false;"> someDivs.each(function() { 	$('#anotherDiv')[0].innerHTML += $(this).text(); }); 
  1. 每次迭代搜索 anotherDiv
  2. 獲取innerHTML 屬性兩次
  3. 創建一個新的 jQuery 對象,全部用于訪問元素的文本。

更好

 var someDivs = $('#container').find('.someDivs'),       contents = [];  someDivs.each(function() { 	contents.push( this.innerHTML ); }); $('#anotherDiv').html( contents.join('') ); 

這樣,在 each (for) 方法中,我們執行的唯一任務就是向數組添加一個新鍵…而不是查詢 DOM,兩次獲取元素的 innerHTML 屬性,等等

這篇技巧總體上更多地基于 JavaScript,而不是特定于 jQuery。 重點是要記住 jQuery 并不能彌補糟糕的編碼。

文檔片段

當我們這樣做時,針對此類情況的另一種選擇是使用文檔片段。

 var someUls = $('#container').find('.someUls'), 	frag = document.createDocumentFragment(), 	li; 	 someUls.each(function() { 	li = document.createElement('li'); 	li.appendChild( document.createTextNode(this.innerHTML) ); 	frag.appendChild(li); });  $('#anotherUl')[0].appendChild( frag ); 

這里的關鍵是,有多種方法可以完成這樣的簡單任務,并且每種方法在瀏覽器之間都有自己的性能優勢。您越堅持使用 jQuery 并學習 JavaScript,您可能還會發現您更頻繁地引用 JavaScript 的本機屬性和方法。如果是這樣,那就太棒了!

jQuery 提供了令人驚嘆的抽象級別,您應該利用它,但這并不意味著您被迫使用它的方法。例如,在上面的片段示例中,我們使用 jQuery 的 each 方法。如果您更喜歡使用 for 或 while 語句,那也沒關系!

盡管如此,請記住 jQuery 團隊已經對該庫進行了大量優化。關于 jQuery 的 each() 與本機 for 語句的爭論是愚蠢而瑣碎的。如果您在項目中使用 jQuery,請使用它們的幫助器方法來節省時間。這就是他們存在的目的! ??


7。 AJAX 方法

如果您現在才開始深入研究 jQuery,它為我們提供的各種 AJAX 方法可能會讓人感到有點畏懼;盡管他們不需要。事實上,它們中的大多數只是簡單的輔助方法,直接路由到 $.ajax。

  • 獲取
  • getJSON
  • 帖子
  • ajax

作為示例,讓我們回顧一下 getJSON,它允許我們獲取 JSON。

 $.getJSON('path/to/json', function(results) { 	// callback 	// results contains the returned data object }); 

在幕后,該方法首先調用 $.get。

 getJSON: function( url, data, callback ) { 	return jQuery.get(url, data, callback, "json"); } 

$.get 然后編譯傳遞的數據,并再次調用“master”(某種意義上的)$.ajax 方法。

 get: function( url, data, callback, type ) { 	// shift arguments if data argument was omited 	if ( jQuery.isFunction( data ) ) { 		type = type || callback; 		callback = data; 		data = null; 	}  	return jQuery.ajax({ 		type: "GET", 		url: url, 		data: data, 		success: callback, 		dataType: type 	}); } 

最后,$.ajax 執行了大量工作,使我們能夠在所有瀏覽器上成功發出異步請求!

這意味著您也可以直接使用 $.ajax 方法來處理您的所有 AJAX 請求。其他方法只是輔助方法,無論如何最終都會執行此操作。所以,如果你愿意的話,就可以去掉中間人。無論如何,這都不是一個重要的問題。

只是花花公子

 $.getJSON('path/to/json', function(results) { 	// callback 	// results contains the returned data object }); 

微觀上更高效

 $.ajax({ 	type: 'GET', 	url : 'path/to/json', 	data : yourData, 	dataType : 'json', 	success : function( results ) { 		console.log('success'); 	}) }); 

8。 訪問本機屬性和方法

現在您已經學習了一些 JavaScript,并且已經了解,例如,在錨標記上,您可以直接訪問屬性值:

 var anchor = document.getElementById('someAnchor');  //anchor.id // anchor.href // anchor.title // .etc 

唯一的問題是,當您使用 jQuery 引用 DOM 元素時,這似乎不起作用,對嗎?當然不是。

不起作用

 	// Fails 	var id = $('#someAnchor').id; 

因此,如果您需要訪問 href 屬性(或任何其他本機屬性或方法),您有多種選擇。

 // OPTION 1 - Use jQuery var id = $('#someAnchor').attr('id');  // OPTION 2 - Access the DOM element var id = $('#someAnchor')[0].id;  // OPTION 3 - Use jQuery's get method var id = $('#someAnchor').get(0).id;  // OPTION 3b - Don't pass an index to get anchorsArray = $('.someAnchors').get(); var thirdId = anchorsArray[2].id; 

get 方法特別有用,因為它可以將 jQuery 集合轉換為數組。


9。 使用 PHP 檢測 AJAX 請求

當然,對于我們的絕大多數項目,我們不能僅僅依賴 JavaScript 來完成諸如驗證或 AJAX 請求之類的事情。當 JavaScript 關閉時會發生什么?正是出于這個原因,一種常見的技術是檢測 AJAX 請求是否是使用您選擇的服務器端語言發出的。

jQuery 通過在 $.ajax 方法中設置標頭,使這變得異常簡單。

 // Set header so the called script knows that it's an XMLHttpRequest // Only send the header if it's not a remote XHR if ( !remote ) { 	xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); } 

設置此標頭后,我們現在可以使用 PHP(或任何其他語言)檢查此標頭,并進行相應操作。為此,我們檢查 $_SERVER[‘HTTP_X_REQUESTED_WITH’] 的值。

包裝器

 function isXhr() {   return $_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest'; } 

10。 jQuery 和 $

有沒有想過為什么/如何可以互換使用 jQuery 和 $ ?要找到答案,請查看 jQuery 源代碼,然后滾動到最底部。在那里,您會看到:

 window.jQuery = window.$ = jQuery; 

當然,整個 jQuery 腳本都包含在一個自執行函數中,這允許腳本盡可能地限制全局變量的數量。但這也意味著 jQuery 對象在包裝匿名函數之外不可用。

為了解決這個問題,jQuery 被暴露給全局 window 對象,并且在此過程中,還會創建一個別名 – $ -。


11。 有條件地加載 jQuery

HTML5 Boilerplate 提供了一個漂亮的單行代碼,如果由于某種奇怪的原因您選擇的 CDN 出現故障,它將加載 jQuery 的本地副本。

 <!-- Grab Google CDN jQuery. fall back to local if necessary --> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script><script>!window.jQuery && document.write('<script src="js/jquery-1.4.2.min.js"></script>')</script>

“表述”上面的代碼:如果 window.jQuery 未定義,則從 CDN 下載腳本時一定出現問題。在這種情況下,請繼續到 && 運算符的右側,并插入鏈接到本地??版本 jQuery 的腳本。


12。 jQuery 過濾器

高級會員:下載此視頻(必須登錄)

訂閱我們的 YouTube 頁面以觀看所有視頻教程!

 <script> 	$('p:first').data('info', 'value'); // populates $'s data object to have something to work with 	 	$.extend( 		jQuery.expr[":"], { 			block: function(elem) { 				return $(elem).css("display") === "block"; 			}, 			 			hasData : function(elem) {				 				return !$.isEmptyObject( $(elem).data() ); 			} 		} 	); 	 	$("p:hasData").text("has data"); // grabs paras that have data attached 	$("p:block").text("are block level"); // grabs only paragraphs that have a display of "block" </script>

注意:jQuery.expr[‘:’] 只是 jQuery.expr.filters 的別名。


13。 單一懸停功能

從 jQuery 1.4 開始,我們現在只能將單個函數傳遞給 hover 方法。以前,inout 方法都是必需的。

之前

 $('#someElement').hover(function() {   // mouseover }, function() {  // mouseout }); 

現在

 $('#someElement').hover(function() {   // the toggle() method can be used here, if applicable }); 

請注意,這不是舊協議與新協議的比較。很多時候,您仍然需要將兩個函數傳遞給 hover,這是完全可以接受的。但是,如果您只需要切換某些元素(或類似的元素),則傳遞單個匿名函數將節省一些字符左右!


14。 傳遞屬性對象

從 jQuery 1.4 開始,我們現在可以傳遞一個對象作為 jQuery 函數的第二個參數。當我們需要向 DOM 中插入新元素時,這非常有用。例如:

之前

 $('<a></a>')   .attr({     id : 'someId',     className : 'someClass',     href : 'somePath.html'   }); 

之后

 $('', {     id : 'someId',     className : 'someClass',     href : 'somePath.html' }); 

這不僅可以節省一些字符,而且還可以使代碼更加簡潔。除了元素屬性之外,我們甚至可以傳遞 jQuery 特定的屬性和事件,例如 click 或 text。


感謝您的閱讀!

? 版權聲明
THE END
喜歡就支持一下吧
點贊12 分享