<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專題視頻專題問答1問答10問答100問答1000問答2000關(guān)鍵字專題1關(guān)鍵字專題50關(guān)鍵字專題500關(guān)鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關(guān)鍵字專題關(guān)鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
        問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
        當(dāng)前位置: 首頁 - 科技 - 知識百科 - 正文

        jQuery源碼分析-03構(gòu)造jQuery對象-工具函數(shù)_jquery

        來源:懂視網(wǎng) 責(zé)編:小采 時(shí)間:2020-11-27 21:01:26
        文檔

        jQuery源碼分析-03構(gòu)造jQuery對象-工具函數(shù)_jquery

        jQuery源碼分析-03構(gòu)造jQuery對象-工具函數(shù)_jquery:作者:nuysoft/高云 QQ:47214707 EMail:nuysoft@gmail.com 聲明:本文為原創(chuàng)文章,如需轉(zhuǎn)載,請注明來源并保留原文鏈接。 讀讀寫寫,不對的地方請告訴我,多多交流共同進(jìn)步,本章的的PDF等本章寫完了發(fā)布。 jQuery源碼分析系列的目錄請查看 htt
        推薦度:
        導(dǎo)讀jQuery源碼分析-03構(gòu)造jQuery對象-工具函數(shù)_jquery:作者:nuysoft/高云 QQ:47214707 EMail:nuysoft@gmail.com 聲明:本文為原創(chuàng)文章,如需轉(zhuǎn)載,請注明來源并保留原文鏈接。 讀讀寫寫,不對的地方請告訴我,多多交流共同進(jìn)步,本章的的PDF等本章寫完了發(fā)布。 jQuery源碼分析系列的目錄請查看 htt

        作者:nuysoft/高云 QQ:47214707 EMail:nuysoft@gmail.com
        聲明:本文為原創(chuàng)文章,如需轉(zhuǎn)載,請注明來源并保留原文鏈接。
        讀讀寫寫,不對的地方請告訴我,多多交流共同進(jìn)步,本章的的PDF等本章寫完了發(fā)布。
        jQuery源碼分析系列的目錄請查看 http://nuysoft.iteye.com/blog/1177451,想系統(tǒng)的好好寫寫,目前還是從我感興趣的部分開始,如果大家有對哪個(gè)模塊感興趣的,建議優(yōu)先分析的,可以告訴我,一起學(xué)習(xí)。
        3.4 其他靜態(tài)工具函數(shù)
        代碼如下:
        // 擴(kuò)展工具函數(shù)
        jQuery.extend({
        // 釋放$的 jQuery 控制權(quán)
        // 許多 JavaScript 庫使用 $ 作為函數(shù)或變量名,jQuery 也一樣。
        // 在 jQuery 中,$ 僅僅是 jQuery 的別名,因此即使不使用 $ 也能保證所有功能性。
        // 假如我們需要使用 jQuery 之外的另一 JavaScript 庫,我們可以通過調(diào)用 $.noConflict() 向該庫返回控制權(quán)。
        // 通過向該方法傳遞參數(shù) true,我們可以將 $ 和 jQuery 的控制權(quán)都交還給另一JavaScript庫。
        noConflict: function( deep ) {
        // 交出$的控制權(quán)
        if ( window.$ === jQuery ) {
        window.$ = _$;
        }
        // 交出jQuery的控制權(quán)
        if ( deep && window.jQuery === jQuery ) {
        window.jQuery = _jQuery;
        }
        return jQuery;
        },
        // Is the DOM ready to be used? Set to true once it occurs.
        isReady: false,
        // A counter to track how many items to wait for before
        // the ready event fires. See #6781
        // 一個(gè)計(jì)數(shù)器,用于跟蹤在ready事件出發(fā)前的等待次數(shù)
        readyWait: 1,
        // Hold (or release) the ready event
        // 繼續(xù)等待或觸發(fā)
        holdReady: function( hold ) {
        if ( hold ) {
        jQuery.readyWait++;
        } else {
        jQuery.ready( true );
        }
        },
        // Handle when the DOM is ready
        // 文檔加載完畢句柄
        ready: function( wait ) {
        // Either a released hold or an DOMready/load event and not yet ready
        //
        if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) {
        // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
        // 確保document.body存在
        if ( !document.body ) {
        return setTimeout( jQuery.ready, 1 );
        }
        // Remember that the DOM is ready
        jQuery.isReady = true;
        // If a normal DOM Ready event fired, decrement, and wait if need be
        if ( wait !== true && --jQuery.readyWait > 0 ) {
        return;
        }
        // If there are functions bound, to execute
        readyList.resolveWith( document, [ jQuery ] );
        // Trigger any bound ready events
        if ( jQuery.fn.trigger ) {
        jQuery( document ).trigger( "ready" ).unbind( "ready" );
        }
        }
        },
        // 初始化readyList事件處理函數(shù)隊(duì)列
        // 兼容不同瀏覽對綁定事件的區(qū)別
        bindReady: function() {
        if ( readyList ) {
        return;
        }
        readyList = jQuery._Deferred();
        // Catch cases where $(document).ready() is called after the
        // browser event has already occurred.
        if ( document.readyState === "complete" ) {
        // Handle it asynchronously to allow scripts the opportunity to delay ready
        return setTimeout( jQuery.ready, 1 );
        }
        // Mozilla, Opera and webkit nightlies currently support this event
        // 兼容事件,通過檢測瀏覽器的功能特性,而非嗅探瀏覽器
        if ( document.addEventListener ) {
        // Use the handy event callback
        // 使用較快的加載完畢事件
        document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
        // A fallback to window.onload, that will always work
        // 注冊window.onload回調(diào)函數(shù)
        window.addEventListener( "load", jQuery.ready, false );
        // If IE event model is used
        } else if ( document.attachEvent ) {
        // ensure firing before onload,
        // maybe late but safe also for iframes
        // 確保在onload之前觸發(fā)onreadystatechange,可能慢一些但是對iframes更安全
        document.attachEvent( "onreadystatechange", DOMContentLoaded );
        // A fallback to window.onload, that will always work
        // 注冊window.onload回調(diào)函數(shù)
        window.attachEvent( "onload", jQuery.ready );
        // If IE and not a frame
        // continually check to see if the document is ready
        var toplevel = false;
        try {
        toplevel = window.frameElement == null;
        } catch(e) {}
        if ( document.documentElement.doScroll && toplevel ) {
        doScrollCheck();
        }
        }
        },
        // See test/unit/core.js for details concerning isFunction.
        // Since version 1.3, DOM methods and functions like alert
        // aren't supported. They return false on IE (#2968).
        // 是否函數(shù)
        isFunction: function( obj ) {
        return jQuery.type(obj) === "function";
        },
        // 是否數(shù)組
        // 如果瀏覽器有內(nèi)置的 Array.isArray 實(shí)現(xiàn),就使用瀏覽器自身的實(shí)現(xiàn)方式,
        // 否則將對象轉(zhuǎn)為String,看是否為"[object Array]"。
        isArray: Array.isArray || function( obj ) {
        return jQuery.type(obj) === "array";
        },
        // A crude way of determining if an object is a window
        // 簡單的判斷(判斷setInterval屬性)是否window對象
        isWindow: function( obj ) {
        return obj && typeof obj === "object" && "setInterval" in obj;
        },
        // 是否是保留字NaN
        isNaN: function( obj ) {
        // 等于null 或 不是數(shù)字 或調(diào)用window.isNaN判斷
        return obj == null || !rdigit.test( obj ) || isNaN( obj );
        },
        // 獲取對象的類型
        type: function( obj ) {
        // 通過核心API創(chuàng)建一個(gè)對象,不需要new關(guān)鍵字
        // 普通函數(shù)不行
        // 調(diào)用Object.prototype.toString方法,生成 "[object Xxx]"格式的字符串
        // class2type[ "[object " + name + "]" ] = name.toLowerCase();
        return obj == null ?
        String( obj ) :
        class2type[ toString.call(obj) ] || "object";
        },
        // 檢查obj是否是一個(gè)純粹的對象(通過"{}" 或 "new Object"創(chuàng)建的對象)
        // console.info( $.isPlainObject( {} ) ); // true
        // console.info( $.isPlainObject( '' ) ); // false
        // console.info( $.isPlainObject( document.location ) ); // true
        // console.info( $.isPlainObject( document ) ); // false
        // console.info( $.isPlainObject( new Date() ) ); // false
        // console.info( $.isPlainObject( ) ); // false
        // isPlainObject分析與重構(gòu) http://www.gxlcms.com/article/25047.htm
        // 對jQuery.isPlainObject()的理解 http://www.cnblogs.com/phpmix/articles/1733599.html
        isPlainObject: function( obj ) {
        // Must be an Object.
        // Because of IE, we also have to check the presence of the constructor property.
        // Make sure that DOM nodes and window objects don't pass through, as well
        // 必須是一個(gè)對象
        // 因?yàn)樵贗E8中會(huì)拋出非法指針異常,必須檢查constructor屬性
        // DOM節(jié)點(diǎn)和window對象,返回false
        // obj不存在 或 非object類型 或 DOM節(jié)點(diǎn) 或 widnow對象,直接返回false
        // 測試以下三中可能的情況:
        // jQuery.type(obj) !== "object" 類型不是object,忽略
        // obj.nodeType 認(rèn)為DOM節(jié)點(diǎn)不是純對象
        // jQuery.isWindow( obj ) 認(rèn)為window不是純對象
        if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
        return false;
        }
        // Not own constructor property must be Object
        // 測試constructor屬性
        // 具有構(gòu)造函數(shù)constructor,卻不是自身的屬性(即通過prototype繼承的),
        if ( obj.constructor &&
        !hasOwn.call(obj, "constructor") &&
        !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
        return false;
        }
        // Own properties are enumerated firstly, so to speed up,
        // if last one is own, then all properties are own.
        var key;
        for ( key in obj ) {}
        // key === undefined及不存在任何屬性,認(rèn)為是簡單的純對象
        // hasOwn.call( obj, key ) 屬性key不為空,且屬性key的對象自身的(即不是通過prototype繼承的)
        return key === undefined || hasOwn.call( obj, key );
        },
        // 是否空對象
        isEmptyObject: function( obj ) {
        for ( var name in obj ) {
        return false;
        }
        return true;
        },
        // 拋出一個(gè)異常
        error: function( msg ) {
        throw msg;
        },
        // 解析JSON
        // parseJSON把一個(gè)字符串變成JSON對象。
        // 我們一般使用的是eval。parseJSON封裝了這個(gè)操作,但是eval被當(dāng)作了最后手段。
        // 因?yàn)樽钚翵avaScript標(biāo)準(zhǔn)中加入了JSON序列化和反序列化的API。
        // 如果瀏覽器支持這個(gè)標(biāo)準(zhǔn),則這兩個(gè)API是在JS引擎中用Native Code實(shí)現(xiàn)的,效率肯定比eval高很多。
        // 目前來看,Chrome和Firefox4都支持這個(gè)API。
        parseJSON: function( data ) {
        if ( typeof data !== "string" || !data ) {
        return null;
        }
        // Make sure leading/trailing whitespace is removed (IE can't handle it)
        data = jQuery.trim( data );
        // Attempt to parse using the native JSON parser first
        // 原生JSON API。反序列化是JSON.stringify(object)
        if ( window.JSON && window.JSON.parse ) {
        return window.JSON.parse( data );
        }
        // Make sure the incoming data is actual JSON
        // Logic borrowed from http://json.org/json2.js
        // ... 大致地檢查一下字符串合法性
        if ( rvalidchars.test( data.replace( rvalidescape, "@" )
        .replace( rvalidtokens, "]" )
        .replace( rvalidbraces, "")) ) {
        return (new Function( "return " + data ))();
        }
        jQuery.error( "Invalid JSON: " + data );
        },
        // Cross-browser xml parsing
        // (xml & tmp used internally)
        // 解析XML 跨瀏覽器
        // parseXML函數(shù)也主要是標(biāo)準(zhǔn)API和IE的封裝。
        // 標(biāo)準(zhǔn)API是DOMParser對象。
        // 而IE使用的是Microsoft.XMLDOM的 ActiveXObject對象。
        parseXML: function( data , xml , tmp ) {
        if ( window.DOMParser ) { // Standard 標(biāo)準(zhǔn)XML解析器
        tmp = new DOMParser();
        xml = tmp.parseFromString( data , "text/xml" );
        } else { // IE IE的XML解析器
        xml = new ActiveXObject( "Microsoft.XMLDOM" );
        xml.async = "false";
        xml.loadXML( data );
        }
        tmp = xml.documentElement;
        if ( ! tmp || ! tmp.nodeName || tmp.nodeName === "parsererror" ) {
        jQuery.error( "Invalid XML: " + data );
        }
        return xml;
        },
        // 無操作函數(shù)
        noop: function() {},
        // Evaluates a script in a global context
        // Workarounds based on findings by Jim Driscoll
        // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
        // globalEval函數(shù)把一段腳本加載到全局context(window)中。
        // IE中可以使用window.execScript。
        // 其他瀏覽器 需要使用eval。
        // 因?yàn)檎麄€(gè)jQuery代碼都是一整個(gè)匿名函數(shù),所以當(dāng)前context是jQuery,如果要將上下文設(shè)置為window則需使用globalEval。
        globalEval: function( data ) {
        // data非空
        if ( data && rnotwhite.test( data ) ) {
        // We use execScript on Internet Explorer
        // We use an anonymous function so that context is window
        // rather than jQuery in Firefox
        ( window.execScript || function( data ) {
        window[ "eval" ].call( window, data );
        } )( data );
        }
        },
        // 判斷節(jié)點(diǎn)名稱是否相同
        nodeName: function( elem, name ) {
        // 忽略大小寫
        return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
        },
        // args is for internal usage only
        // 遍歷對象或數(shù)組
        each: function( object, callback, args ) {
        var name, i = 0,
        length = object.length,
        isObj = length === undefined || jQuery.isFunction( object );
        // 如果有參數(shù)args,調(diào)用apply,上下文設(shè)置為當(dāng)前遍歷到的對象,參數(shù)使用args
        if ( args ) {
        if ( isObj ) {
        for ( name in object ) {
        if ( callback.apply( object[ name ], args ) === false ) {
        break;
        }
        }
        } else {
        for ( ; i < length; ) {
        if ( callback.apply( object[ i++ ], args ) === false ) {
        break;
        }
        }
        }
        // A special, fast, case for the most common use of each
        // 沒有參數(shù)args則調(diào)用,則調(diào)用call,上下文設(shè)置為當(dāng)前遍歷到的對象,參數(shù)設(shè)置為key/index和value
        } else {
        if ( isObj ) {
        for ( name in object ) {
        if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
        break;
        }
        }
        } else {
        for ( ; i < length; ) {
        if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) {
        break;
        }
        }
        }
        }
        return object;
        },
        // Use native String.trim function wherever possible
        // 盡可能的使用本地String.trim方法,否則先過濾開頭的空格,再過濾結(jié)尾的空格
        trim: trim ?
        function( text ) {
        return text == null ?
        "" :
        trim.call( text );
        } :
        // Otherwise use our own trimming functionality
        function( text ) {
        return text == null ?
        "" :
        text.toString().replace( trimLeft, "" ).replace( trimRight, "" );
        },
        // results is for internal usage only
        // 將偽數(shù)組轉(zhuǎn)換為數(shù)組
        makeArray: function( array, results ) {
        var ret = results || [];
        if ( array != null ) {
        // The window, strings (and functions) also have 'length'
        // The extra typeof function check is to prevent crashes
        // in Safari 2 (See: #3039)
        // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930
        // 一大堆瀏覽器兼容性測試,真實(shí)蛋疼
        var type = jQuery.type( array );
        // 測試:有沒有l(wèi)ength屬性、字符串、函數(shù)、正則
        // 不是數(shù)組,連偽數(shù)組都不是
        if ( array.length == null
        || type === "string"
        || type === "function"
        || type === "regexp"
        || jQuery.isWindow( array ) ) {
        push.call( ret, array );
        } else {
        // $.type( $('div') ) // object
        jQuery.merge( ret, array );
        }
        }
        return ret;
        },
        //
        inArray: function( elem, array ) {
        // 是否有本地化的Array.prototype.indexOf
        if ( indexOf ) {
        // 直接調(diào)用Array.prototype.indexOf
        return indexOf.call( array, elem );
        }
        // 遍歷數(shù)組,查找是否有完全相等的元素,并返回下標(biāo)
        // 循環(huán)的小技巧:把a(bǔ)rray.length存放到length變量中,可以減少一次作用域查找
        for ( var i = 0, length = array.length; i < length; i++ ) {
        if ( array[ i ] === elem ) {
        return i;
        }
        }
        // 如果返回-1,則表示不在數(shù)組中
        return -1;
        },
        // 將數(shù)組second合并到數(shù)組first中
        merge: function( first, second ) {
        var i = first.length, //
        j = 0;
        // 如果second的length屬性是Number類型,則把second當(dāng)數(shù)組處理
        if ( typeof second.length === "number" ) {
        for ( var l = second.length; j < l; j++ ) {
        first[ i++ ] = second[ j ];
        }
        } else {
        // 遍歷second,將非undefined的值添加到first中
        while ( second[j] !== undefined ) {
        first[ i++ ] = second[ j++ ];
        }
        }
        // 修正first的length屬性,因?yàn)閒irst可能不是真正的數(shù)組
        first.length = i;
        return first;
        },
        // 過濾數(shù)組,返回新數(shù)組;callback返回true時(shí)保留;如果inv為true,callback返回false才會(huì)保留
        grep: function( elems, callback, inv ) {
        var ret = [], retVal;
        inv = !!inv;
        // Go through the array, only saving the items
        // that pass the validator function
        // 遍歷數(shù)組,只保留通過驗(yàn)證函數(shù)callback的元素
        for ( var i = 0, length = elems.length; i < length; i++ ) {
        // 這里callback的參數(shù)列表為:value, index,與each的習(xí)慣一致
        retVal = !!callback( elems[ i ], i );
        // 是否反向選擇
        if ( inv !== retVal ) {
        ret.push( elems[ i ] );
        }
        }
        return ret;
        },
        // arg is for internal usage only
        // 將數(shù)組或?qū)ο骵lems的元素/屬性,轉(zhuǎn)化成新的數(shù)組
        map: function( elems, callback, arg ) {
        var value, key, ret = [],
        i = 0,
        length = elems.length,
        // jquery objects are treated as arrays
        // 檢測elems是否是(偽)數(shù)組
        // 1. 將jQuery對象也當(dāng)成數(shù)組處理
        // 2. 檢測length屬性是否存在,length等于0,或第一個(gè)和最后一個(gè)元素是否存在,或jQuery.isArray返回true
        isArray = elems instanceof jQuery
        || length !== undefined && typeof length === "number"
        && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ;
        // 是數(shù)組或?qū)ο蟮牟顒e,僅僅是遍歷的方式不同,沒有其他的區(qū)別
        // Go through the array, translating each of the items to their
        // 遍歷數(shù)組,對每一個(gè)元素調(diào)用callback,將返回值不為null的值,存入ret
        if ( isArray ) {
        for ( ; i < length; i++ ) {
        // 執(zhí)行callback,參數(shù)依次為value, index, arg
        value = callback( elems[ i ], i, arg );
        // 如果返回null,則忽略(無返回值的function會(huì)返回undefined)
        if ( value != null ) {
        ret[ ret.length ] = value;
        }
        }
        // Go through every key on the object,
        // 遍歷對象,對每一個(gè)屬性調(diào)用callback,將返回值不為null的值,存入ret
        } else {
        for ( key in elems ) {
        // 執(zhí)行callback,參數(shù)依次為value, key, arg
        value = callback( elems[ key ], key, arg );
        // 同上
        if ( value != null ) {
        ret[ ret.length ] = value;
        }
        }
        }
        // Flatten any nested arrays
        // 使嵌套數(shù)組變平
        // concat:
        // 如果某一項(xiàng)為數(shù)組,那么添加其內(nèi)容到末尾。
        // 如果該項(xiàng)目不是數(shù)組,就將其作為單個(gè)的數(shù)組元素添加到數(shù)組的末尾。
        return ret.concat.apply( [], ret );
        },
        // A global GUID counter for objects
        guid: 1,
        // Bind a function to a context, optionally partially applying any
        // arguments.
        // 代理方法:為fn指定上下文(即this)
        // jQuery.proxy( function, context )
        // jQuery.proxy( context, name )
        proxy: function( fn, context ) {
        // 如果context是字符串,設(shè)置上下文為fn,fn為fn[ context ]
        // 即設(shè)置fn的context方法的上下文為fn(默認(rèn)不是這樣嗎???TODO)
        if ( typeof context === "string" ) {
        var tmp = fn[ context ];
        context = fn;
        fn = tmp;
        }
        // Quick check to determine if target is callable, in the spec
        // this throws a TypeError, but we will just return undefined.
        // 快速測試fn是否是可調(diào)用的(即函數(shù)),在文檔說明中,會(huì)拋出一個(gè)TypeError,
        // 但是這里僅返回undefined
        if ( !jQuery.isFunction( fn ) ) {
        return undefined;
        }
        // Simulated bind
        var args = slice.call( arguments, 2 ), // 從參數(shù)列表中去掉fn,context
        proxy = function() {
        // 設(shè)置上下文為context和參數(shù)
        return fn.apply( context, args.concat( slice.call( arguments ) ) );
        };
        // Set the guid of unique handler to the same of original handler, so it can be removed
        // 統(tǒng)一guid,使得proxy能夠被移除
        proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
        return proxy;
        },
        // Mutifunctional method to get and set values to a collection
        // The value/s can be optionally by executed if its a function
        // 多功能函數(shù),讀取或設(shè)置集合的屬性值;值為函數(shù)時(shí)會(huì)被執(zhí)行
        // fn:jQuery.fn.css, jQuery.fn.attr, jQuery.fn.prop
        access: function( elems, key, value, exec, fn, pass ) {
        var length = elems.length;
        // Setting many attributes
        // 如果有多個(gè)屬性,則迭代
        if ( typeof key === "object" ) {
        for ( var k in key ) {
        jQuery.access( elems, k, key[k], exec, fn, value );
        }
        return elems;
        }
        // Setting one attribute
        // 只設(shè)置一個(gè)屬性
        if ( value !== undefined ) {
        // Optionally, function values get executed if exec is true
        exec = !pass && exec && jQuery.isFunction(value);
        for ( var i = 0; i < length; i++ ) {
        fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
        }
        return elems;
        }
        // Getting an attribute
        // 讀取屬性
        return length ? fn( elems[0], key ) : undefined;
        },
        // 獲取當(dāng)前時(shí)間的便捷函數(shù)
        now: function() {
        return (new Date()).getTime();
        },
        // Use of jQuery.browser is frowned upon.
        // More details: http://docs.jquery.com/Utilities/jQuery.browser
        // 不贊成使用jQuery.browser,推薦使用jQuery.support
        // Navigator 正在使用的瀏覽器的信息
        // Navigator.userAgent 一個(gè)只讀的字符串,聲明了瀏覽器用于HTPP請求的用戶代理頭的值
        uaMatch: function( ua ) {
        ua = ua.toLowerCase();
        // 依次匹配各瀏覽器
        var match = rwebkit.exec( ua ) ||
        ropera.exec( ua ) ||
        rmsie.exec( ua ) ||
        ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) ||
        [];
        // match[1] || ""
        // match[1]為false(空字符串、null、undefined、0等)時(shí),默認(rèn)為""
        // match[2] || "0"
        // match[2]為false(空字符串、null、undefined、0等)時(shí),默認(rèn)為"0"
        return { browser: match[1] || "", version: match[2] || "0" };
        },
        // 創(chuàng)建一個(gè)新的jQuery副本,副本的屬性和方法可以被改變,但是不會(huì)影響原始的jQuery對象
        // 有兩種用法:
        // 1. 覆蓋jQuery的方法,而不破壞原始的方法
        // 2.封裝,避免命名空間沖突,可以用來開發(fā)jQuery插件
        // 值得注意的是,jQuery.sub()函數(shù)并不提供真正的隔離,所有的屬性、方法依然指向原始的jQuery
        // 如果使用這個(gè)方法來開發(fā)插件,建議優(yōu)先考慮jQuery UI widget工程
        sub: function() {
        function jQuerySub( selector, context ) {
        return new jQuerySub.fn.init( selector, context );
        }
        jQuery.extend( true, jQuerySub, this ); // 深度拷貝,將jQuery的所有屬性和方法拷貝到j(luò)QuerySub
        jQuerySub.superclass = this;
        jQuerySub.fn = jQuerySub.prototype = this(); //
        jQuerySub.fn.constructor = jQuerySub;
        jQuerySub.sub = this.sub;
        jQuerySub.fn.init = function init( selector, context ) {
        if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) {
        context = jQuerySub( context );
        }
        return jQuery.fn.init.call( this, selector, context, rootjQuerySub );
        };
        jQuerySub.fn.init.prototype = jQuerySub.fn;
        var rootjQuerySub = jQuerySub(document);
        return jQuerySub;
        },
        // 瀏覽器類型和版本:
        // $.browser.msie/mozilla/webkit/opera
        // $.browser.version
        // 不推薦嗅探瀏覽器類型jQuery.browser,而是檢查瀏覽器的功能特性jQuery.support
        // 未來jQuery.browser可能會(huì)移到一個(gè)插件中
        browser: {}
        });

        聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

        jQuery源碼分析-03構(gòu)造jQuery對象-工具函數(shù)_jquery

        jQuery源碼分析-03構(gòu)造jQuery對象-工具函數(shù)_jquery:作者:nuysoft/高云 QQ:47214707 EMail:nuysoft@gmail.com 聲明:本文為原創(chuàng)文章,如需轉(zhuǎn)載,請注明來源并保留原文鏈接。 讀讀寫寫,不對的地方請告訴我,多多交流共同進(jìn)步,本章的的PDF等本章寫完了發(fā)布。 jQuery源碼分析系列的目錄請查看 htt
        推薦度:
        標(biāo)簽: 代碼 函數(shù) jQuery
        • 熱門焦點(diǎn)

        最新推薦

        猜你喜歡

        熱門推薦

        專題
        Top
        主站蜘蛛池模板: 亚洲国产成人精品无码区二本| 亚洲国产精品va在线播放| 亚洲不卡中文字幕| 99久久国产热无码精品免费| 亚洲视频一区调教| 最近高清中文字幕免费| 亚洲黄色免费在线观看| 69成人免费视频| 亚洲性无码一区二区三区| 国产精品99久久免费| 99精品视频在线免费观看 | 97久久免费视频| 亚洲日韩中文字幕| 野花高清在线电影观看免费视频 | 亚洲色成人网站WWW永久四虎| 一二三四在线播放免费观看中文版视频 | 久久精品国产亚洲夜色AV网站| 毛片在线播放免费观看| 337p日本欧洲亚洲大胆艺术| 5555在线播放免费播放| 亚洲午夜精品第一区二区8050| 亚洲成综合人影院在院播放| 久久受www免费人成_看片中文| 亚洲国产精品自在自线观看| 亚洲精品国产电影| 一级毛片免费播放| 亚洲成a∧人片在线观看无码| 亚洲v国产v天堂a无码久久| 少妇性饥渴无码A区免费| 亚洲一区二区久久| 成人亚洲网站www在线观看| 亚洲免费观看视频| 中中文字幕亚洲无线码| 免费一级e一片在线播放| 亚洲视频在线观看免费| 亚洲中文字幕无码mv| 狠狠色婷婷狠狠狠亚洲综合 | 亚洲国产精品99久久久久久| 精品亚洲成α人无码成α在线观看| 久久免费动漫品精老司机| 2020久久精品亚洲热综合一本|