javascript 點點滴滴 jquery
1 ;(function(global, factory) { 2 factory(global); 3 }(typeof window !== "undefined" ? window : this, function(window, noGlobal) { 4 var jQuery = function( selector, context ) { 5 return new jQuery.fn.init( selector, context ); 6 }; 7 jQuery.fn = jQuery.prototype = {};8 // 核心方法 9 // 回調系統 10 // 異步隊列 11 // 數據緩存 12 // 隊列操作 13 // 選擇器引 14 // 屬性操作 15 // 節點遍歷 16 // 文檔處理 17 // 樣式操作 18 // 屬性操作 19 // 事件體系 20 // AJAX交互 21 // 動畫引擎 22 return jQuery; 23 }));
- 任何庫與框架設計的第一個要點就是解決命名空間與變量汙染的問題。
- jQuery就是利用了JavaScript函數作用域的特性,
- 采用立即調用表達式包裹了自身的方法來解決這個問題。
- window和undefined都是為了減少變量查找所經過的scope作用域。
- 當window通過傳遞給閉包內部之後,在閉包內部使用它的時候,
- 可以把它當成一個局部變量,顯然比原先在window scope下查找的時候要快一些。
- 為什麽要傳遞undefined?
- Javascript 中的 undefined 並不是作為關鍵字,因此可以允許用戶對其賦值。
jQuery使用()將匿名函數括起來,然後後面再加一對小括號(包含參數列表),那麽這小括號能把我們的表達式組合分塊,並且每一塊(也就是每一對小括號),都有一個返 回值。這個返回值實際上也就是小括號中表達式的返回值。所以,當我們用一對小括號把匿名函數括起來的時候,實際上小括號返回的,就是一個匿名函數的Function對象。 因此,小括號對加上匿名函數就如同有名字的函數般被我們取得它的引用位置了。所以如果在這個引用變量後面再加上參數列表,就會實現普通函數的調用形式。
1 jQuery有3種針對文檔加載的方法 2 3 $(document).ready(function() { 4 // ...代碼... 5 }) 6 //document ready 簡寫 7 $(function() { 8 // ...代碼... 9 }) 10 $(document).load(function() { 11 // ...代碼... 12 })
(1) 解析HTML結構。 (2) 加載外部腳本和樣式表文件。 (3) 解析並執行腳本代碼。 (4) 構造HTML DOM模型。//ready (5) 加載圖片等外部文件。 (6) 頁面加載完畢。//load
ready在第(4)步完成之後就執行了,但是load要在第(6)步完成之後才執行。
jQuery.ready.promise = function( obj ) { if ( !readyList ) { readyList = jQuery.Deferred(); if ( document.readyState === "complete" ) { // Handle it asynchronously to allow scripts the opportunity //to delay ready setTimeout( jQuery.ready ); } else { document.addEventListener( "DOMContentLoaded", completed, false ); window.addEventListener( "load", completed, false ); } } return readyList.promise( obj ); };
// Ensure firing before onload, maybe late but safe also for iframes document.attachEvent( "onreadystatechange", completed ); // A fallback to window.onload, that will always work window.attachEvent( "onload", completed ); // If IE and not a frame // continually check to see if the document is ready var top = false; try { top = window.frameElement == null && document.documentElement; } catch(e) {} if ( top && top.doScroll ) { (function doScrollCheck() { if ( !jQuery.isReady ) { try { // Use the trick by Diego Perini // http://javascript.nwbox.com/IEContentLoaded/ top.doScroll("left"); } catch(e) { return setTimeout( doScrollCheck, 50 ); } // detach all dom ready events detach(); // and execute any waiting functions jQuery.ready(); } })(); }
如果瀏覽器存在 document.onreadystatechange
事件,
當該事件觸發時,如果 document.readyState=complete
的時候,可視為 DOM 樹已經載入。
不過,這個事件不太可靠,比如當頁面中存在圖片的時候,可能反而在 onload 事件之後才能觸發
針對IE的加載檢測
Diego Perini 在 2007 年的時候,報告了一種檢測 IE 是否加載完成的方式,使用 doScroll 方法調用,詳情可見http://javascript.nwbox.com/IEContentLoaded/。
原理就是對於 IE 在非 iframe 內時,只有不斷地通過能否執行 doScroll 判斷 DOM 是否加載完畢。在上述中間隔 50 毫秒嘗試去執行 doScroll,註意,由於頁面沒有加載完成的時候,調用 doScroll 會導致異常,所以使用了 try -catch 來捕獲異常。
結論:所以總的來說當頁面 DOM 未加載完成時,調用 doScroll 方法時,會產生異常。那麽我們反過來用,如果不異常,那麽就是頁面DOM加載完畢了。
if ( document.readyState === "complete" ) { // Handle it asynchronously to allow scripts the opportunity to delay ready setTimeout( jQuery.ready ); }
直接通過查看readyState的狀態來確定頁面的加載是否完成了。這裏會給一個定時器的最小時間後去執行,主要保證執行的正確。
Var _jQuery = window.jQuery, _$ = window.$; jQuery.noConflict = function( deep ) { if ( window.$ === jQuery ) { window.$ = _$; } if ( deep && window.jQuery === jQuery ) { window.jQuery = _jQuery; } return jQuery; };
- 如果我們需要同時使用jQuery和其他JavaScript庫,我們可以使用 $.noConflict()把$的控制權交給其他庫。
- 舊引用的$ 被保存在jQuery的初始化; noConflict() 簡單的恢復它們。
- 通過類似swap交換的概念,先把之前的存在的命名空間給緩存起來,
- 通過對比當前的命名空間達到交換的目的,首先,我們先判斷下當前的的$空間是不是被jQuery接管了,
- 如果是則讓出控制權給之前的_$引用的庫,如果傳入deep為true的話等於是把jQuery的控制權也讓出去了。
javascript 點點滴滴 jquery