關於jQuery的 入門使用jQuery可以很容易或具有挑戰性的,這取決於你如何使用JavaScript,HTML,CSS進行開發和編程。 要知道一件重要的事情是,jQuery是只是一個JavaScript庫。jQuery的所有功能特性都是通過JavaScript訪問,所以要對javascript足 ...
關於jQuery的
入門使用jQuery可以很容易或具有挑戰性的,這取決於你如何使用JavaScript,HTML,CSS進行開發和編程。
要知道一件重要的事情是,jQuery是只是一個JavaScript庫。jQuery的所有功能特性都是通過JavaScript訪問,所以要對javascript足夠的理解,並能使其構建和調試代碼是必不可少。雖然使用jQuery定期工作可以隨著時間的推移,提高使用JavaScript的熟練程度,可能沒有JavaScript的內置結構和語法的應用知識寫jQuery很難上手。因此,如果你是新來的JavaScript,我們建議您查看的JavaScript基礎教程 Mozilla開發者網路(MDN)上,想瞭解jquery的具體javascript實現原理可去http://youmightnotneedjquery.com/
如何jQuery的工作原理
jQuery的:基礎知識
這是一個基本的教程,旨在幫助您使用jQuery上手。如果你沒有一個測試頁面設置呢,通過創建以下的HTML頁面開始:
1 2 3 4 五 6 7 8 9 10 11 12 13 14 15 16 |
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Demo</title>
</head>
<body>
<a href="http://jquery.com/">jQuery</a>
<script src="jquery.js"></script>
<script>
// Your code goes here.
</script>
</body>
</html>
|
該src
屬性中的<script>
元素必須指向jQuery的副本。從下載的jQuery的副本下載jQuery的頁面和存儲jquery.js
文件在同一目錄作為您的HTML文件。
jquery-x.y.z.js
。請確保該文件或者重命名jquery.js
或更新src
的屬性<script>
相匹配的文件名元素。
文檔準備啟動代碼
為了確保他們的代碼運行在瀏覽器完成載入該文件,許多JavaScript程式員包裝自己的代碼在後的onload
功能:
1 2 3 4 五 |
window.onload = function() {
alert( "welcome" );
};
|
不幸的是儘快運行代碼的文件已準備好進行操作,代碼不運行,直到所有圖像都下載完畢,包括橫幅廣告。jQuery ready事件:
1 2 3 4 五 |
$( document ).ready(function() {
// Your code here.
});
|
window
調用的對象jQuery
和$
,$
是一個簡單的別名jQuery
,它的經常使用,因為它是更短,更快地寫。
例如,在裡面ready
時,你可以添加一個單擊處理程式的鏈接:
1 2 3 4 五 6 7 8 9 |
$( document ).ready(function() {
$( "a" ).click(function( event ) {
alert( "Thanks for visiting!" );
});
});
|
上面的jQuery代碼複製到你的HTML文件,它說// Your code goes here
。然後,保存您的HTML文件,然後在瀏覽器中刷新測試頁。點擊鏈接現在應該先顯示一個警告彈出,然後繼續導航到的預設行為http://jquery.com。
對於click
大部分其他的事件,您可以通過調用阻止預設行為event.preventDefault()
的事件處理程式:
1 2 3 4 五 6 7 8 9 10 11 |
$( document ).ready(function() {
$( "a" ).click(function( event ) {
alert( "As you can see, the link no longer took you to jquery.com" );
event.preventDefault();
});
});
|
嘗試更換您的jQuery代碼,先前複製到您的HTML文件中第一個片段,與上面的之一。再次保存HTML文件並重新載入嘗試一下。
完整的示例
下麵的例子說明點擊上面的處理代碼的討論,直接在HTML嵌入<body>
。註意,在實踐中,它通常是最好將代碼在一個單獨的JS文件並載入它與在頁面上<script>
的元素的src
屬性。
1 2 3 4 五 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Demo</title>
</head>
<body>
<a href="http://jquery.com/">jQuery</a>
<script src="jquery.js"></script>
<script>
$( document ).ready(function() {
$( "a" ).click(function( event ) {
alert( "The link will no longer take you to jquery.com" );
event.preventDefault();
});
});
</script>
</body>
</html>
|
添加和刪除一個HTML類
重要提示:您必須將裡面剩餘的jQuery的例子ready
事件,這樣,當文檔準備工作在你的代碼執行。
另一種常見的任務就是添加或刪除類。
首先,添加一些樣式信息寫入<head>
文件,像這樣的:
|
<style>
a.test {
font-weight: bold;
}
</style>
|
接下來,添加.addClass()調用腳本:
1 |
$( "a" ).addClass( "test" );
|
所有的<a>
元素現在字體加粗。
要刪除現有類中,使用.removeClass() :
1 |
$( "a" ).removeClass( "test" );
|
特效
jQuery的也提供了一些方便的效果,以幫助您使您的網站脫穎而出。例如,如果你創建一個click處理函數:
1 2 3 4 五 6 7 |
$( "a" ).click(function( event ) {
event.preventDefault();
$( this ).hide( "slow" );
});
|
然後單擊時慢慢鏈接消失。
回調和函數
不像許多其他編程語言,JavaScript的,可以自由地繞過功能在稍後的時間執行。一個回調是作為參數傳遞給另一個函數傳遞與其父功能完成後執行的函數。回調是特殊的,因為他們耐心地等待執行,直到他們的父母完成。同時,瀏覽器可以執行其它功能或做其他各種的工作。
要使用回調,要知道如何將它們傳遞到它們的父功能是非常重要的。
回調不爭論
如果回調沒有參數,你可以將它傳遞這樣的:
1 |
$.get( "myhtmlpage.html", myCallBack );
|
當$獲得()完獲取的頁面myhtmlpage.html
,它執行myCallBack()
的功能。
- 註:這裡的第二個參數是簡單的函數名稱(而不是作為一個字元串,而沒有括弧)。
回調與參數
帶參數執行回調可能會非常棘手。
錯誤
此代碼示例將無法正常工作:
1 |
$.get( "myhtmlpage.html", myCallBack( param1, param2 ) );
|
失敗的原因是,代碼執行myCallBack( param1, param2 )
立即,然後通過myCallBack()
的返回值作為第二個參數$.get()
。實際上,我們希望傳遞給函數myCallBack()
,而不是myCallBack( param1, param2 )
的返回值(這可能是也可能不是一個函數)。那麼,如何傳遞myCallBack()
和包括它的參數?
推遲執行myCallBack()
其參數,你可以使用匿名函數作為包裝。使用註意事項function() {
。匿名函數正是一件事:通話myCallBack()
,用的價值觀param1
和param2
。
1 2 3 4 五 |
$.get( "myhtmlpage.html", function() {
myCallBack( param1, param2 );
});
|
當$.get()
完成後獲得的頁面myhtmlpage.html
,它執行的匿名函數,該函數執行myCallBack( param1, param2 )
。
優化選擇器
選擇器的使用是對性能有很大的考驗,所以在使用選擇器的時候需要小心了。
jQuery的擴展
如果可能的話,應避使用jQuery的擴展選擇器。這些擴展不能利用由本機提供的性能提升的querySelectorAll()
DOM方法,因此,需要使用的jQuery提供的選擇器引擎。
1 2 3 4 五 |
// Slower (the zero-based :even selector is a jQuery extension)
$( "#my-table tr:even" );
// Better, though not exactly equivalent
$( "#my-table tr:nth-child(odd)" );
|
請記住,很多jQuery的擴展,包括:even
在上面的例子中,沒有在CSS規範內。在某些情況下,這些擴展的便利性可能超過其性能成本。
避免過度特異性
1 2 3 4 |
$( ".data table.attendees td.gonzalez" );
// Better: Drop the middle if possible.
$( ".data td.gonzalez" );
|
一個“簡介的”DOM也有助於提高性能的選擇,因為選擇器引擎有更少的層尋找一個跨度的元素。
基於ID選擇器
一個id選擇器有一定的安全性。
1 2 3 4 五 |
// Fast:
$( "#container div.robotarm" );
// Super-fast:
$( "#container" ).find( "div.robotarm" );
|
與第一種方法相比,jQuery的查詢使用DOM document.querySelectorAll()
。第二個例子中,jQuery使用document.getElementById()
,這是更快。
提示舊的瀏覽器
當舊的瀏覽器,如Internet Explorer 8和下方支撐,是必要的,請考慮以下建議:
特異性
選擇器的左右側
1 2 3 4 五 |
// Unoptimized:
$( "div.data .gonzalez" );
// Optimized:
$( ".data td.gonzalez" );
|
使用tag.class
如果可能的話放選擇器的最右邊,只是標簽或只.class在選擇器的最左邊
。
避免通用選擇
通配符選擇雖然會減少代碼做更多事情 ,但是效率很低。
1 2 3 4 五 6 |
$( ".buttons > *" ); // Extremely expensive.
$( ".buttons" ).children(); // Much better.
$( ":radio" ); // Implied universal selection.
$( "*:radio" ); // Same thing, explicit now.
$( "input:radio" ); // Much better.
|
代碼組織概念
當你超越添加簡單的改進自己的網站使用jQuery並開始制定全面的客戶端應用程式,你需要考慮如何組織你的代碼。在本章中,我們將看看你可以在你的jQuery應用程式中使用的各種代碼的組織模式和探索RequireJS依賴管理和構建系統。
關鍵概念
之前,我們跳進代碼的組織模式,瞭解一些概念是所有好的代碼的組織模式是很重要的。
- 您的代碼應分為功能單位-模塊,服務等,因此要避免把所有的代碼在一個巨大的
$( document ).ready()
塊。這個概念,鬆散的,被稱為封裝。 - 不要重覆自己。找出相似的功能塊之間,並使用繼承技術,以避免重覆的代碼。
- 儘管jQuery的DOM為中心的性質,JavaScript應用程式是不是所有的DOM。請記住,不是所有的功能塊需要 - 或者應該 - 有一個DOM表示。
- 功能單位應松耦合,即,功能單元應該能夠在其自己的存在,和單元之間的通信應經由消息收發系統,諸如自定義事件或發佈/訂閱處理。功能單元之間保持直接溝通遠只要有可能。
鬆散耦合的概念可能是特別麻煩的開發人員使他們的第一次涉足複雜的應用程式,從而為您開始留心這一點。
封裝
第一步代碼組織分離您的應用程式為不同的組件; 有時,甚至只是這方面的做的好才滿足開發需要。
對象常量
一個對象字面也許是封裝相關的代碼最簡單的方法。它不提供屬性或方法的任何隱私的,但它是消除匿名函數從代碼中,集中的配置選項,並簡化重用和重構的路徑非常有用。
1 2 3 4 五 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
// An object literal
var myFeature = {
myProperty: "hello",
myMethod: function() {
console.log( myFeature.myProperty );
},
init: function( settings ) {
myFeature.settings = settings;
},
readSettings: function() {
console.log( myFeature.settings );
}
};
myFeature.myProperty === "hello"; // true
myFeature.myMethod(); // "hello"
myFeature.init({
foo: "bar"
});
myFeature.readSettings(); // { foo: "bar" }
|
對象上面的文字簡直是分配給一個變數的對象。對象具有一個屬性和幾種方法。所有屬性和方法都是公開的,因此您的應用程式的任何部分可以看到該對象的屬性和調用方法。雖然有一個init方法,沒有什麼需要之前的對象是功能,它被調用。
我們如何應用此模式jQuery代碼?比方說,我們有這個代碼寫在傳統的jQuery風格:
1 2 3 4 五 6 7 8 9 10 11 12 |
// Clicking on a list item loads some content using the
// list item's ID, and hides content in sibling list items
$( document ).ready(function() {
$( "#myFeature li" ).append( "<div>" ).click(function() {
var item = $( this );
var div = item.find( "div" );
div.load( "foo.php?item=" + item.attr( "id" ), function() {
div.show();
item.siblings().find( "div" ).hide();
});
});
});
|
如果這是我們的應用程式的範圍,這樣的應用是不好的。在另一方面,如果這是一塊更大的應用程式中,我們會做的很好,保持這個功能不相關的功能分開。我們可能還需要移動URL出代碼,併成為一個配置區域。最後,我們可能要提取鏈接地址,使其更容易為以後修改的功能塊。
1 2 3 4 五 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 三十 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
// Using an object literal for a jQuery feature
var myFeature = {
init: function( settings ) {
myFeature.config = {
items: $( "#myFeature li" ),
container: $( "<div class='container'></div>" ),
urlBase: "/foo.php?item="
};
// Allow overriding the default config
$.extend( myFeature.config, settings );
myFeature.setup();
},
setup: function() {
myFeature.config.items
.each( myFeature.createContainer )
.click( myFeature.showItem );
},
createContainer: function() {
var item = $( this );
var container = myFeature.config.container
.clone()
.appendTo( item );
item.data( "container", container );
},
buildUrl: function() {
return myFeature.config.urlBase + myFeature.currentItem.attr( "id" );
},
showItem: function() {
myFeature.currentItem = $( this );
myFeature.getContent( myFeature.showContent );
},
getContent: function( callback ) {
var url = myFeature.buildUrl();
myFeature.currentItem.data( "container" ).load( url, callback );
},
showContent: function() {
myFeature.currentItem.data( "container" ).show();
myFeature.hideContent();
},
hideContent: function() {
myFeature.currentItem.siblings().each(function() {
$( this ).data( "container" ).hide();
});
}
};
$( document ).ready( myFeature.init );
|
你會註意到的第一件事是,這種做法顯然比原來要長 - 再次,如果這是我們的應用程式的範圍,使用對象文本很可能是矯枉過正。假設這不是我們的應用程式的範圍,雖然,我們已經獲得了幾件事情:
- 我們已經打破我們的功能成微小的方法。在未來,如果我們想改變內容的顯示方式,很明顯的地方去改變它。在最初的代碼中,這一步是更難找到。
- 我們已經消除了使用匿名函數。
- 我們已經搬出了代碼的主體配置選項,並把它們在一個中央位置。
- 我們已經消除了鏈條的制約,使代碼更易於重構,重新混音和重新排列。
對於重要的功能,對象文本一條長長的代碼明顯改善$( document ).ready()
塊,因為他們讓我們思考我們的功能塊。然而,他們不是一大堆不僅僅是具有內部一堆函數聲明更先進的$( document ).ready()
塊。
模塊模式
模塊模式剋服一些對象的文字的限制,提供變數和函數的隱私,同時如果需要的話曝光公共API。
1 2 3 4 五 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
// The module pattern
var feature = (function() {
// Private variables and functions
var privateThing = "secret";
var publicThing = "not secret";
var changePrivateThing = function() {
privateThing = "super secret";
};
var sayPrivateThing = function() {
console.log( privateThing );
changePrivateThing();
};
// Public API
return {
publicThing: publicThing,
sayPrivateThing: sayPrivateThing
};
})();
feature.publicThing; // "not secret"
// Logs "secret" and changes the value of privateThing
feature.sayPrivateThing();
|
在上面的例子中,我們自執行返回的對象的匿名函數。裡面的功能,我們定義了一些變數。因為變數的函數的內部定義,我們不具有的功能的外部訪問它們,除非我們把它們返回的對象。這意味著函數以外沒有代碼訪問該privateThing
變數或往changePrivateThing
功能。不過,sayPrivateThing
也有機會獲得privateThing
和changePrivateThing
,因為兩人都在同一範圍定義sayPrivateThing
。
這種模式是強大的,因為你可以從變數名聚集,它可以給你私人的變數和函數同時揭露包括返回的對象的屬性和方法的有限的API。
下麵是前面的例子的修訂版本,展示我們可以如何使用模塊模式,而只有露出模塊的一個公共方法創建相同的功能,showItemByIndex()
。
1 2 3 4 五 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 三十 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
// Using the module pattern for a jQuery feature
$( document ).ready(function() {
var feature = (function() {
var items = $( "#myFeature li" );
var container = $( "<div class='container'></div>" );
var currentItem = null;
var urlBase = "/foo.php?item=";
var createContainer = function() {
var item = $( this );
var _container = container.clone().appendTo( item );
item.data( "container", _container );
};
var buildUrl = function() {
return urlBase + currentItem.attr( "id" );
};
var showItem = function() {
currentItem = $( this );
getContent( showContent );
};
var showItemByIndex = function( idx ) {
$.proxy( showItem, items.get( idx ) );
};
var getContent = function( callback ) {
currentItem.data( "container" ).load( buildUrl(), callback );
};
var showContent = function() {
currentItem.data( "container" ).show();
hideContent();
};
var hideContent = function() {
currentItem.siblings().each(function() {
$( this ).data( "container" ).hide();
});
};
items.each( createContainer ).click( showItem );
return {
showItemByIndex: showItemByIndex
};
})();
feature.showItemByIndex( 0 );
});
|