1.當document文件就緒時執行JavaScript程式碼。
我們為什麼使用jQuery庫呢?原因之一就在於我們可以使jQuery程式碼在各種不同的瀏覽器和存在bug的瀏覽器上完美執行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
<script src="http://code.jquery.com/jquery-1.10.2.min.js"></script> <script> // Different ways to achieve the Document Ready event // With jQuery $(document).ready(function(){ /* ... */}); // Short jQuery $(function(){ /* ... */}); // Without jQuery (doesn't work in older IE versions) document.addEventListener('DOMContentLoaded',function(){ // Your code goes here }); // The Trickshot (works everywhere): r(function(){ alert('DOM Ready!'); }) function r(f){/in/.test(document.readyState)?setTimeout('r('+f+')',9):f()} </script> |
2.使用route。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
<script src="http://code.jquery.com/jquery-1.10.2.min.js"></script> <script> var route = { _routes : {}, // The routes will be stored here add : function(url, action){ this._routes[url] = action; }, run : function(){ jQuery.each(this._routes, function(pattern){ if(location.href.match(pattern)){ // "this" points to the function to be executed this(); } }); } } // Will execute only on this page: route.add('002.html', function(){ alert('Hello there!') }); route.add('products.html', function(){ alert("this won't be executed :(") }); // You can even use regex-es: route.add('.*.html', function(){ alert('This is using a regex!') }); route.run(); </script> |
3.使用JavaScript中的AND技巧。
使用&&操作符的特點是如果操作符左邊的表示式是false,那麼它就不會再判斷操作符右邊的表示式了。所以:
1 2 3 4 5 6 7 8 |
// Instead of writing this: if($('#elem').length){ // do something } // You can write this: $('#elem').length && log("doing something"); |
4. is()方法比你想象的更為強大。
下面舉幾個例子,我們先寫一個id為elem的div。js程式碼如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
// First, cache the element into a variable: var elem = $('#elem'); // Is this a div? elem.is('div') && log("it's a div"); // Does it have the bigbox class? elem.is('.bigbox') && log("it has the bigbox class!"); // Is it visible? (we are hiding it in this example) elem.is(':not(:visible)') && log("it is hidden!"); // Animating elem.animate({'width':200},1); // is it animated? elem.is(':animated') && log("it is animated!"); |
其中判斷是否為動畫我覺得非常不錯。
5.判斷你的網頁一共有多少元素。
通過使用$(“*”).length屬性可以判斷網頁的元素數量。
1 2 |
// How many elements does your page have? log('This page has ' + $('*').length + ' elements!'); |
6.使用length()屬性很笨重,下面我們使用exist()方法。
1 2 3 4 5 6 7 8 |
// Old way log($('#elem').length == 1 ? "exists!" : "doesn't exist!"); // Trickshot: jQuery.fn.exists = function(){ return this.length > 0; } log($('#elem').exists() ? "exists!" : "doesn't exist!"); |
7.jQuery方法$()實際上是擁有兩個引數的,你知道第二個引數的作用嗎?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
// Select an element. The second argument is context to limit the search // You can use a selector, jQuery object or dom element $('li','#firstList').each(function(){ log($(this).html()); }); log('-----'); // Create an element. The second argument is an // object with jQuery methods to be called var div = $('<div>',{ "class": "bigBlue", "css": { "background-color":"purple" }, "width" : 20, "height": 20, "animate" : { // You can use any jQuery method as a property! "width": 200, "height":50 } }); div.appendTo('#result'); |
8.使用jQuery我們可以判斷一個連結是否是外部的,並來新增一個icon在非外部連結中,且確定開啟方式。
這裡用到了hostname屬性。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<ul id="links"> <li><a href="007.html">The previous tip</a></li> <li><a href="./009.html">The next tip</a></li> <li><a href="http://www.google.com/">Google</a></li> </ul> // Loop through all the links $('#links a').each(function(){ if(this.hostname != location.hostname){ // The link is external $(this).append('<img src="assets/img/external.png" />') .attr('target','_blank'); } }); |
9.jQuery中的end()方法可以使你的jQuery鏈更加高效。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<ul id="meals"> <li> <ul class="breakfast"> <li class="eggs">No</li> <li class="toast">No</li> <li class="juice">No</li> </ul> </li> </ul> // Here is how it is used: var breakfast = $('#meals .breakfast'); breakfast.find('.eggs').text('Yes') .end() // back to breakfast .find('.toast').text('Yes') .end() .find('.juice').toggleClass('juice coffee').text('Yes'); breakfast.find('li').each(function(){ log(this.className + ': ' + this.textContent) }); |
10.也許你希望你的web 應用感覺更像原生的,那麼你可以阻止contextmenu預設事件。
1 2 3 4 5 6 7 8 |
<script> // Prevent right clicking on this page $(function(){ $(document).on("contextmenu",function(e){ e.preventDefault(); }); }); </script> |
11.一些站點可能會使你的網頁在一個bar下面,即我們所看到在下面的網頁是iframe標籤中的,我們可以這樣解決。
1 2 3 4 5 6 7 8 |
// Here is how it is used: if(window != window.top){ window.top.location = window.location; } else{ alert('This page is not displayed in a frame. Open 011.html to see it in action.'); } |
12.你的內聯樣式表並不是被設定為不可改變的,如下:
1 2 3 |
// Make the stylesheet visible and editable $('#regular-style-block').css({'display':'block', 'white-space':'pre'}) .attr('contentEditable',true); |
這樣即可改變內聯樣式了。
13.有時候我們不希望網頁的某一部分內容被選擇比如複製貼上這種事情,我們可以這麼做:
1 2 3 4 5 6 7 8 9 10 |
<p class="descr">In certain situations you might want to prevent text on the page from being selectable. Try selecting this text and hit view source to see how it is done.</p> <script> // Prevent text from being selected $(function(){ $('p.descr').attr('unselectable', 'on') .css('user-select', 'none') .on('selectstart', false); }); </script> |
這樣,內容就不能被選擇啦。
14.從CDN中引入jQuery,這樣的方法可以提高我們網站的效能,並且引入最新的版本也是一個不錯的主意。
下面會介紹四種不同的方法。
1 2 3 4 5 6 7 8 9 10 11 |
<!-- Case 1 - requesting jQuery from the official CDN --> <script src="http://code.jquery.com/jquery-1.10.2.min.js"></script> <!-- Case 2 - requesting jQuery from Google's CDN (notice the protocol) --> <!-- <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script> --> <!-- Case 3 - requesting the latest minor 1.8.x version (only cached for an hour) --> <!-- <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10/jquery.min.js"></script> --> <!-- Case 4 - requesting the absolute latest jQuery version (use with caution) --> <!-- <script src="http://code.jquery.com/jquery.min.js"></script> --> |
15.保證最小的DOM操作。
我們知道js操作DOM是非常浪費資源的,我們可以看看下面的例子。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
CODE // Bad //var elem = $('#elem'); //for(var i = 0; i < 100; i++){ // elem.append('<li>element '+i+'</li>'); //} // Good var elem = $('#elem'), arr = []; for(var i = 0; i < 100; i++){ arr.push('<li>element '+i+'</li>'); } elem.append(arr.join('')); |
16.更方便的分解URL。
也許你會使用正規表示式來解析URL,但這絕對不是一種好的方法,我們可以借用a標籤來實現它。
1 2 3 4 5 6 7 8 9 10 11 |
// You want to parse this address into parts: var url = 'http://tutorialzine.com/books/jquery-trickshots?trick=12#comments'; // The trickshot: var a = $('<a>',{ href: url }); log('Host name: ' + a.prop('hostname')); log('Path: ' + a.prop('pathname')); log('Query: ' + a.prop('search')); log('Protocol: ' + a.prop('protocol')); log('Hash: ' + a.prop('hash')); |
17.不要害怕使用vanilla.js。
jQuery揹負的太多,這便是原因,你可以用一般的js。
1 2 3 4 5 6 7 8 9 |
// Print the IDs of all LI items $('#colors li').each(function(){ // Access the ID directly, instead // of using jQuery's $(this).attr('id') log(this.id); }); |
18.最優化你的選擇器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
// Let's try some benchmarks! var iterations = 10000, i; timer('Fancy'); for(i=0; i < iterations; i++){ // This falls back to a SLOW JavaScript dom traversal $('#peanutButter div:first'); } timer_result('Fancy'); timer('Parent-child'); for(i=0; i < iterations; i++){ // Better, but still slow $('#peanutButter div'); } timer_result('Parent-child'); timer('Parent-child by class'); for(i=0; i < iterations; i++){ // Some browsers are a bit faster on this one $('#peanutButter .jellyTime') |
19.快取你的selector。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
// Bad: // $('#pancakes li').eq(0).remove(); // $('#pancakes li').eq(1).remove(); // $('#pancakes li').eq(2).remove(); // Good: var pancakes = $('#pancakes li'); pancakes.eq(0).remove(); pancakes.eq(1).remove(); pancakes.eq(2).remove(); // Alternatively: // pancakes.eq(0).remove().end() // .eq(1).remove().end() // .eq(2).remove().end(); |
20.對於重複的函式只定義一次
如果你追求程式碼的更高效能,那麼當你設定事件監聽程式時必須小心,只定義一次函式然後把它的名字作為事件處理程式傳遞是不錯的方法。
1 2 3 4 5 6 7 8 9 10 |
$(document).ready(function(){ function showMenu(){ alert('Showing menu!'); // Doing something complex here } $('#menuButton').click(showMenu); $('#menuLink').click(showMenu); }); |
21.像對待陣列一樣地對待jQuery物件
由於jQuery物件有index值和長度,所以這意味著我們可以把物件當作普通的陣列對待。這樣也會有更好地效能。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
var arr = $('li'), iterations = 100000; timer('Native Loop'); for(var z=0;z<iterations;z++){ var length = arr.length; for(var i=0; i < length; i++){ arr[i]; } } timer_result('Native Loop'); timer('jQuery Each'); for(z=0;z<iterations;z++){ arr.each(function(i, val) { this; }); } timer_result('jQuery Each'); |
22.當做複雜的修改時要分離元素。
修改一個dom元素要求網頁重繪,這個代價是高昂的,所以如果你想要再提高效能,就可以嘗試著當對一個元素進行大量修改時先從頁面中分離這個元素,修改完之後再新增到頁面。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
// Modifying in place var elem = $('#elem'); timer('In place'); for(i=0; i < iterations; i++){ elem.width(Math.round(100*Math.random())); elem.height(Math.round(100*Math.random())); } timer_result('In place'); var parent = elem.parent(); // Detaching first timer('Detached'); elem.detach(); for(i=0; i < iterations; i++){ elem.width(Math.round(100*Math.random())); elem.height(Math.round(100*Math.random())); } elem.appendTo(parent); timer_result('Detached'); |
23.不要一直等待load事件。
我們已經習慣了把我們所有的程式碼都放在ready的事件處理程式中,但是,如果你的html頁面很龐大,decument ready恐怕會被延遲了,所以對於一些我們不希望ready後才可以觸發的事件可以放在html的head元素中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
<script> // jQuery is loaded at this point. We can use // event delegation right away to bind events // even before $(document).ready: $(document).on('click', '#clickMe', function(){ alert('Hit view source and see how this is made'); }); $(document).ready(function(){ // This is where you would usually bind event handlers, // but as we are using delegation, there is no need to. // $('#clickMe').click(function(){ alert('Hey!'); }); }); // Note: You should place your script tags at the bottom of the page. // I have included them in the head only to demonstrate that we can bind // events before document ready and before the elements are created. </script> |
24.當使用js給多個元素新增樣式時更好的做法是建立一個style元素。
我們之前提到過,操作dom是非常慢的,所以當新增多個元素的樣式時建立一個style元素並新增到document中是更好的做法。
1 2 3 4 5 6 7 8 9 10 11 |
<ul id="testList"> <li>Item</li> <li>Item</li> <li>Item</li> <li>Item</li> <li>Item</li> <li>Item</li> <li>Item</li> <li>Item</li> <li>Item</li> <li>Item</li> <li>Item</li> <li>Item</li> <li>Item</li> <li>Item</li> <li>Item</li> <li>Item</li> <li>Item</li> </ul> var style = $('<style>'); // Try commenting out this line, or change the color: style.text('#testList li{ color:red;}'); // Placing it before the result section so it affects the elements style.prependTo('#result'); |
25.給html元素分配一個名為JS的class。
現代的web apps非常的依賴js,這裡的一個技巧就是隻有當js可用時才能顯示特定的元素。看下面的程式碼。
1 2 3 4 5 6 7 |
$(document).ready(function(){ $('html').addClass('JS'); }); html.JS #message { display:block; } #message {display:none;} |
這樣,只有js可用的時候id為message的元素才會顯示;如果不支援js,則該元素不會顯示。
26.監聽不存在的元素上的事件。
jQuery擁有一個先進的事件處理機制,通過on()方法可以監聽還不存在的事件。 這是因為on方法可以傳遞一個元素的子元素選擇器作為引數。看下面的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<ul id="testList"> <li>Old</li> <li>Old</li> <li>Old</li> <li>Old</li> </ul> var list = $('#testList'); // Binding an event on the list, but listening for events on the li items: list.on('click','li',function(){ $(this).remove(); }); // This allows us to create li elements at a later time, // while keeping the functionality in the event listener list.append('<li>New item (click me!)</li>'); |
這樣,即使li是後建立的,也可以通過on()方法來監聽。
27.只使用一次事件監聽。
有時,我們只需要繫結只執行一次的事件處理程式。那麼one()方法是一個不錯的選擇,通過它你就可以高枕無憂了。
1 2 3 4 5 6 7 8 9 10 11 |
<button id="press">Press me!</ul> var press = $('#press'); // There is a method that does exactly that, the one(): press.one('click',function(){ alert('This alert will pop up only once'); }); // What this method does, is call on() behind the scenes, // with a 1 as the last argument: // press.on('click',null,null,function(){alert('I am the one and only!');}, 1); |
28.模擬觸發事件。
我們可以通過使用trigger模擬觸發一個click事件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<button id="press">Press me!</ul> var press = $('#press'); // Just a regular event listener: press.on('click',function(e, how){ how = how || ''; alert('The buton was clicked ' + how + '!'); }); // Trigger the click event press.trigger('click'); // Trigger it with an argument press.trigger('click',['fast']); |
29.使用觸控事件。
使用觸控事件和相關的滑鼠事件並沒有太多不同,但是你得有一個方便的移動裝置來測試會更好。看下面這個例子。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
// Define some variables var ball = $('<div id="ball"></div>').appendTo('body'), startPosition = {}, elementPosition = {}; // Listen for mouse and touch events ball.on('mousedown touchstart',function(e){ e.preventDefault(); // Normalizing the touch event object e = (e.originalEvent.touches) ? e.originalEvent.touches[0] : e; // Recording current positions startPosition = {x: e.pageX, y: e.pageY}; elementPosition = {x: ball.offset().left, y: ball.offset().top}; // These event listeners will be removed later ball.on('mousemove.rem touchmove.rem',function(e){ e = (e.originalEvent.touches) ? e.originalEvent.touches[0] : e; ball.css({ top:elementPosition.y + (e.pageY - startPosition.y), left: elementPosition.x + (e.pageX - startPosition.x), }); }); }); ball.on('mouseup touchend',function(){ // Removing the heavy *move listeners ball.off('.rem'); |
30.更好地使用on()/off()方法。
在jQuery1.7版本時對事件處理進行了簡化,看看下面的例子吧。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 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 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
<div id="holder"> <button id="button1">1</button> <button id="button2">2</button> <button id="button3">3</button> <button id="button4">4</button> <button id="clear" style="float: right;">Clear</button> </div> // Lets cache some selectors var button1 = $('#button1'), button2 = $('#button2'), button3 = $('#button3'), button4 = $('#button4'), clear = $('#clear'), holder = $('#holder'); // Case 1: Direct event handling button1.on('click',function(){ log('Click'); }); // Case 2: Direct event handling of multiple events button2.on('mouseenter mouseleave',function(){ log('In/Out'); }); // Case 3: Data passing button3.on('click', Math.round(Math.random()*20), function(e){ // This will print the same number over and over again, // as the random number above is generated only once: log('Random number: ' + e.data); }); // Case 4: Events with a namespace button4.on('click.temp', function(e){ log('Temp event!'); }); button2.on('click.temp', function(e){ log('Temp event!'); }); // Case 5: Using event delegation $('#holder').on('click', '#clear', function(){ log.clear(); }); // Case 6: Passing an event map var t; // timer clear.on({ 'mousedown':function(){ t = new Date(); }, 'mouseup':function(){ if(new Date() - t > 1000){ // The button has been held pressed // for more than a second. Turn off // the temp events $('button').off('.temp'); alert('The .temp events were cleared!'); } } }); |
31.更快地阻止預設事件行為。
我們知道js中可以使用preventDefault()方法來阻止預設行為,但是jQuery對此提供了更簡單的方法。如下:
1 2 3 |
<a href="http://google.com/" id="goToGoogle">Go To Google</a> $('#goToGoogle').click(false); |
32.使用event.result連結多個事件處理程式。
對一個元素繫結多個事件處理程式並不常見,而使用event.result更可以將多個事件處理程式聯絡起來。看下面的例子。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<button id="press">點選</button> <script src="http://code.jquery.com/jquery-1.10.2.min.js"></script> <script> var press = $('#press'); press.on('click',function(){ return 'Hip'; }); // The second event listener has access // to what was returned from the first press.on('click',function(e){ console.log(e.result + ' Hop!'); }); </script> |
這樣,控制檯會輸出Hip Hop!
33.建立你自己習慣的事件。
你可以使用on()方法建立自己喜歡的事件名稱,然後通過trigger來觸發。舉例如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
<button id="button1">Jump</button> <button id="button2">Punch</button> <button id="button3">Click</button> <button id="clear" style="float: right;">Clear</button> <div id="eventDiv"></div> <script src="http://code.jquery.com/jquery-1.10.2.min.js"></script> <script> var button1 = $('#button1'), button2 = $('#button2'), button3 = $('#button3'), clear = $('#clear'), div = $('#eventDiv'); div.on({ jump : function(){ alert('Jumped!'); }, punch : function(e,data){ alert('Punched '+data+'!'); }, click : function(){ alert('Simulated click!'); } }); button1.click(function(){ div.trigger('jump'); }); button2.click(function(){ // Pass data along with the event div.trigger('punch',['hard']); }); button3.click(function(){ div.trigger('click'); }); clear.click(function(){ //some clear code }); </script> |
34.在下載檔案旁顯示檔案大小。
你知道如何在不下載一個檔案的情況下通過傳送一個ajax請求頭得到一個檔案的大小嗎? 使用jQuery就很容易。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
<a href="001.html" class="fetchSize">First Trickshot</a> <br /> <a href="034.html" class="fetchSize">This Trickshot</a> <br /> <a href="assets/img/ball.png" class="fetchSize">Ball.png</a> <br /> // Loop all .fetchSize links $('a.fetchSize').each(function(){ // Issue an AJAX HEAD request for each one var link = this; $.ajax({ type : 'HEAD', url : link.href, complete : function(xhr){ // Append the filesize to each $(link).append(' (' + humanize(xhr.getResponseHeader('Content-Length')) + ')'); } }); }); function humanize(size){ var units = ['bytes','KB','MB','GB','TB','PB']; var ord = Math.floor( Math.log(size) / Math.log(1024) ); ord = Math.min( Math.max(0,ord), units.length-1); var s = Math.round((size / Math.pow(1024,ord))*100)/100; return s + ' ' + units[ord]; } |
注意:這個例子如何我們直接使用瀏覽器是沒法得到的,必須使用本地的web伺服器開啟執行才可以。
35.使用延遲簡化你的Ajax請求
延遲(deferreds)是一個強大的工具。jQuery對於每一個Ajax請求都會返回一個deferred物件。 deferred.done()
方法接受一個或多個引數,所有這些都引數可以是一個單一的函式或一個函式陣列。當Deferred(延遲)解決時,doneCallbacks被呼叫。回撥是依照他們新增的順序執行。一旦deferred.done()
返回Deferred(延遲)物件,Deferred(延遲)可以連結其它的延遲物件,包括增加額外的.done()
方法。下面這樣就會使你的程式碼更易讀:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
// This is equivalent to passing a callback as the // second argument (executed on success): $.get('assets/misc/1.json').done(function(r){ log(r.message); }); // Requesting a file that does not exist. This will trigger // the failure response. To handle it, you would normally have to // use the full $.ajax method and pass it as a failure callback, // but with deferreds you can can simply use the fail method: $.get('assets/misc/non-existing.json').fail(function(r){ log('Oops! The second ajax request was "' + r.statusText + '" (error ' + r.status + ')!'); }); |
36.平行的執行多個Ajax請求。
當我們需要傳送多個Ajax請求是,相反於等待一個傳送結束再傳送下一個,我們可以平行地傳送來加速Ajax請求傳送。
1 2 3 4 5 |
// The trick is in the $.when() function: $.when($.get('assets/misc/1.json'), $.get('assets/misc/2.json')).then(function(r1, r2){ log(r1[0].message + " " + r2[0].message); }); |
37.通過jQuery獲得ip
我們不僅可以在電腦上ping到一個網站的ip,也可以通過jQuery得到。
1 2 3 4 |
$.get('http://jsonip.com/', function(r){ log(r.ip); }); // For older browsers, which don't support CORS // $.getJSON('http://jsonip.com/?callback=?', function(r){ log(r.ip); }); |
38.使用最簡單的ajax請求
jQuery(使用ajax)提供了一個速記的方法來快速下載內容並新增在一個元素中。
1 2 3 4 5 6 7 8 9 |
<p class="content"></p> <p class="content"></p> var contentDivs = $('.content'); // Fetch the contents of a text file: contentDivs.eq(0).load('1.txt'); // Fetch the contents of a HTML file, and display a specific element: contentDivs.eq(1).load('1.html #header'); |
39.序列化物件
jQuery提供了一個方法序列化表單值和一般的物件成為URL編碼文字字串。這樣,我們就可以把序列化的值傳給ajax()作為url的引數,輕鬆使用ajax()提交表單了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<form action=""> First name: <input type="text" name="FirstName" value="Bill" /><br /> Last name: <input type="text" name="LastName" value="Gates" /><br /> </form> // Turn all form fields into a URL friendly key/value string. // This can be passed as argument of AJAX requests, or URLs. $(document).ready(function(){ console.log($("form").serialize()); // FirstName=Bill&LastName=Gates }); // You can also encode your own objects with the $.param method: log($.param({'pet':'cat', 'name':'snowbell'})); |
40.使用jQuery上傳二進位制檔案
現在的瀏覽器都支援FormData API,這可以是我們很輕鬆的通過ajax來傳送資料。 並將之結合HTML5中的File API,我們就可以上傳二進位制檔案了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
// The file input field var fileInput = $('input[type=file]'), button = $('#upload'); button.on('click', function(){ // Access the files property, which holds // an array with the selected files var files = fileInput.prop('files'); // No file was chosen! if(files.length == 0) { alert('Please choose a file to upload!'); return false; } // Create a new FormData object var fd = new FormData(); fd.append('file', files[0]); // Upload the file to assets/php/upload.php. Open that file in a text // editor to get a better idea of how it works. $.ajax({ url: './assets/php/upload.php', data: fd, contentType:false, // This will make the browser use the multipart/formdata encoding, which is required for transferring binary data. processData:false, // jQuery shouldn't do any processsing on the data - the browser will handle this when it sees we are passing a formdata object. type:'POST', success: function(m){ log(m); } }); }); |
41.使用Facebook的圖表
我們可以引入facebook中的一個很強大的API來是我們的app更加社交化。下面是一個簡單的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
CODE // Fetch the publicly accessible data on Tutorialzine's Page var api = 'http://graph.facebook.com/Tutorialzine/?callback=?', holder = $('#fbdata'); $.getJSON(api, function(r){ // This will always give the current picture holder.append('<img src="http://graph.facebook.com/Tutorialzine/picture/?type=large">'); holder.append('<p>'+ r.about +'</p>') holder.append('<a href="'+ r.website +'">'+ r.website +'</a>'); }); |
42.獲取天氣資訊
Open Weather Map提供了免費的天氣資訊,我們可以通過使用它們的JSON API來獲取資料。簡單的例子如下:
1 2 3 4 5 6 7 8 9 10 11 |
// Request weather data: var api = 'http://openweathermap.org/data/2.1/find/name?q=paris,france&callback=?'; $.getJSON(api, function(r){ // This will always give the current picture log(r.list[0].name + ', ' + r.list[0].sys.country); log(r.list[0].main); // Temperatures are in kelvin, subtract 273.15 to convert to Celsius, }); |
43. 獲取你的最近的湯博樂(Tumblr)內容
現在非常流行的湯博樂部落格服務提供了簡單的方法使用JSON api, 這樣我們可以使用它來獲取任何部落格內容,下面是使用的方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<div id="post"></div> // Define variables var blog = 'minimaldesks.tumblr.com', api = 'http://' + blog + '/api/read/json?callback=?', post = $('#post'); $.getJSON(api, function(r){ log('Blog title: ' + r.tumblelog.title); log('Description: ' + r.tumblelog.description); // If this post has a photo, show it if(r.posts[0]['photo-url-250']){ post.append('<img src="' + r.posts[0]['photo-url-250'] + '" />'); } else{ log('Latest post: ' + r.posts[0]['regular-title']); } }); |
44.通過IP地址獲得地理位置
有很多線上服務可以告訴我們IP地址所在的城市和國家,下面我們先ping到百度的IP地址,然後獲取其地理位置:
1 2 3 4 5 6 7 8 9 10 |
// Define variables var ip = '119.75.218.70', // you can optionally put an ip address here api = 'http://freegeoip.net/json/' + ip + '?callback=?'; $.getJSON(api, function(r){ console.log('How is the weather in ' + r.city + ', ' + r.country_name + '?'); }); //How is the weather in Beijing, China? |
45.使用YQL來爬網站
YQL對JavaScript開發者來說有無限的API,下面的例子是我們如何使用它來獲取並解析其他站點的HTML。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
CODE // Define variables var query = 'select * from data.html.cssselect where url="http://www.chucknorrisfacts.com/chuck-norris-top-50-facts" and css=".field-content a"'; var yqlAPI = 'http://query.yahooapis.com/v1/public/yql?q=' + encodeURIComponent(query) + ' &format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=?'; $.getJSON(yqlAPI, function(r){ log('Chuck Norris Facts:'); $.each(r.query.results.results.a, function(){ log('----------'); log(this.content); }); }); |
46.使用全域性的Ajax方法
我們可以通過ajax的全域性方法來簡化web app中處理的ajax請求。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
CODE // Create an indicator that would be shown whenever an AJAX request occurs: var preloader = $('<div>',{ 'class':'preloader' }).appendTo('body'); var doc = $(document); // Show the preloader whenever you are making an AJAX request: doc.ajaxStart(function(){ preloader.fadeIn(); }); // Hide it when the ajax request finishes doc.ajaxComplete(function(){ // Keep it visible for 0.8 seconds after the request completes preloader.delay(800).fadeOut(); }); // It will show automatically every time you do an AJAX request: $.get('assets/misc/1.json'); |
47. 學會愛上console吧。
我們的瀏覽器給了我們一系列有用的方法使用來除錯程式碼,找出bug,下面就是一個例子,開啟console看看吧。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
// The simple case. Use this instead of alert(): console.log('This is a console message!'); // It supports embedding of variables as well: var a = 'morning', b = 'Miss'; console.log('Good %s %s! How are you feeling today?', a, b); // Interactively browse the properties of a method (similar to console.log): console.dir(window); // Information message (in webkit it looks like console.log) console.info('Everything is OK'); // Warning message console.warn('Something may be wrong'); // Error message (will print a stack trace) console.error('Ooops. That was bad.'); // Counting things for(var i = 0; i<20; i++){ console.count('Counter Name'); } // Starts a collapsable group of log messages console.group("Preflight check"); console.info('Fuel is OK'); console.info('Temperature is normal'); console.error('Wings are missing'); console.groupEnd() // Timing things console.time('The million-dollar loop') var dollars = 0; for(var i=0;i<100000; i++){ dollars+=10; } console.timeEnd('The million-dollar loop'); // Profiling code (it will show up in your console's Profile tab) console.profile('My app performance'); var arr = []; $.each([0,1,2,3,4,5,6,7,8,9],function(){ arr.push(this+1); }); console.profileEnd('My app performance'); |
48.把程式碼轉化為外掛以提高重用率。
如果有一些程式碼你總是在不同的專案之間複製貼上,你就可以考慮著把它轉化成一個外掛了。下面的例子就是這樣。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
<input id="testInput" placeholder="YourName"/> <script src="http://code.jquery.com/jquery-1.10.2.min.js"></script> <script> // Define the placeholder plugin $.fn.placeholder = function(){ if ('placeholder' in document.createElement('input')){ // This browser already supports placeholders. // Nothing to do here. return this; } this.each(function(){ var input = $(this); input.on('focus', function(){ if(input.val() == input.attr('placeholder')){ input.val(''); } }).on('blur', function(){ if(input.val() == ''){ input.val(input.attr('placeholder')); } }); // Show the placeholder on load input.trigger('blur'); }); return this; }; // And here is how to use it: $('#testInput').placeholder(); |
49.使用匿名函式來產生一個獨立的程式碼塊
定義全域性變數和函式是一種程式碼很粗糙的行為,更好的方式是通過使用匿名函式使你的程式碼獨立於塊之中。看下面的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
// Isolating a block of code: (function($){ // Declare a variable. It will only be visible in this block. var c = 1; // Define a simple plugin $.fn.count = function(){ // Increment and log the counter log(c++); return this; }; })(jQuery); // The c variable is only visible for the plugin and will keep // its value between invocations: $(document).count(); $('body').count().count(); |
50. 用extend融合物件
當提到從多個專案到一個專案結合屬性時,你最好的猜測就是擴充套件方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 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 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
// Combine properties (useful in plugins). // The defaults are passed as the first argument. var supplied = { height: 400 }; var options = $.extend({ color : 'blue', width : 200, height : 150 }, supplied); log('New options:', options); // You can also pass more than one object log('Three parents:', $.extend({a:2}, {b:3}, {c:4}) ); log('-------'); // Cloning objects. // To clone an object, simply pass an empty one // as the first argument var original = {a:123, b:'#fff'}; var clone = $.extend({}, original); log('Clone:', clone); log('-------'); // Extending jQuery. // You can define plugins with extend $.extend($.fn, { plugin1: function(){ log('Plugin 1'); return this; }, plugin2: function(){ log('Plugin 2'); return this; } }); $('body').plugin1().plugin2(); log('-------'); // If you pass only one arguments to $.extend, // it will add the properties to the jQuery object $.extend({ dontDoThis : 123}); log($.dontDoThis); log('-------'); // Deep cloning. // If you have nested objects, you will have to // pass one additional argument to extend: var obj1 = { a: 1, b: 2, c: {d: 3} }; var obj2 = { c: {e: 4}, f:5}; // This won't work // $.extend(obj1, obj2); // This will $.extend(true, obj1,obj2); log('Deep clone:', obj1); |
持續更新中…