博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
jquery1.7.2的源码分析(二)
阅读量:5165 次
发布时间:2019-06-13

本文共 18857 字,大约阅读时间需要 62 分钟。

jquery.extend

jQuery.extend = jQuery.fn.extend = function () {var options, name, src, copy, copyIsArray, clone,//target为传入的一个参数    target = arguments[0] || {},    i = 1,//传入参数的个数    length = arguments.length,//首先默认为浅拷贝    deep = false;// Handle a deep copy situationif (typeof target === "boolean") {//当第一个参数是布尔值deep = target;//target第二个参数target = arguments[1] || {};// skip the boolean and the targeti = 2;}//当target不是object并且不是functionif (typeof target !== "object" && !jQuery.isFunction(target)) {target = {};}// extend jQuery itself if only one argument is passed//当是一个参数的时候$.extend({ccc:function(){}})if (length === i) {//target为init对象target = this;--i;}for (; i < length; i++) {// Only deal with non-null/undefined valuesif ((options = arguments[i]) != null) { // Extend the base object    for (name in options) {        src = target[name];        copy = options[name];// Prevent never-ending loop        if (target === copy) {            continue;        }//// Recurse if we're merging plain objects or arrays//深拷贝        if (deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) )) {            if (copyIsArray) {                copyIsArray = false;//判断原先的属性存在,存在后再判断是否是数组,不是的话赋值为空数组                clone = src && jQuery.isArray(src) ? src : [];            } else {//判断原先的属性存在,存在后再判断是否是对象,不是的话赋值为空对象                clone = src && jQuery.isPlainObject(src) ? src : {};            }// Never move original objects, clone them            target[name] = jQuery.extend(deep, clone, copy);// Don't bring in undefined values        } else if (copy !== undefined) {//将方法复制到当前对象            target[name] = copy;        }    }}}// Return the modified objectreturn target;};};

jquery.extend的使用

jQuery.extend({    noConflict: function( deep ) {        if ( window.$ === jQuery ) {            window.$ = _$;        }        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    readyWait: 1,// Hold (or release) the ready event    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//wait=true且jQuery.readyWait-1取非为true 或者wait为false jQuery.isReady为false        if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) {// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).\//当不存在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.fireWith( document, [ jQuery ] );// Trigger any bound ready events            if ( jQuery.fn.trigger ) {                jQuery( document ).trigger( "ready" ).off( "ready" );            }        }    },    bindReady: function() {        console.log(readyList)        if ( readyList ) {            return;        }        readyList = jQuery.Callbacks( "once memory" );// 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.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            document.attachEvent( "onreadystatechange", DOMContentLoaded );// A fallback to window.onload, that will always work            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).    isFunction: function( obj ) {        return jQuery.type(obj) === "function";    },    isArray: Array.isArray || function( obj ) {        return jQuery.type(obj) === "array";    },    isWindow: function( obj ) {        return obj != null && obj == obj.window;    },    isNumeric: function( obj ) {        return !isNaN( parseFloat(obj) ) && isFinite( obj );    },    type: function( obj ) {        return obj == null ?                String( obj ) :        class2type[ toString.call(obj) ] || "object";    },//纯对象的判断    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        if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {            return false;        }        try {// Not own constructor property must be Object            if ( obj.constructor &&                    !hasOwn.call(obj, "constructor") &&                    !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {                return false;            }        } catch ( e ) {// IE8,9 Will throw exceptions on certain host objects #9897            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 ) {}        return key === undefined || hasOwn.call( obj, key );    },    isEmptyObject: function( obj ) {        for ( var name in obj ) {//如果有元素就说明不是空的对象            return false;        }        return true;    },    error: function( msg ) {        throw new Error( msg );    },    parseJSON: function( data ) {//字符串转化为json        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        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    parseXML: function( data ) {        if ( typeof data !== "string" || !data ) {            return null;        }        var xml, tmp;        try {            if ( window.DOMParser ) { // Standard                tmp = new DOMParser();                xml = tmp.parseFromString( data , "text/xml" );            } else { // IE                xml = new ActiveXObject( "Microsoft.XMLDOM" );                xml.async = "false";                xml.loadXML( data );            }        } catch( e ) {            xml = undefined;        }        if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) {            jQuery.error( "Invalid XML: " + data );        }        return xml;    },    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: function( 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 );        }    },// Convert dashed to camelCase; used by the css and data modules// Microsoft forgot to hump their vendor prefix (#9572)    camelCase: function( string ) {        return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );    },//例如当string为“-ms-aaaa” 得到的是msAaa;//rmsPrefix = /^-ms-/,第一个replace结束后得到 ms-aaa//rdashAlpha = /-([a-z]|[0-9])/ig,第二个replace 匹配了-a fcamelCase(all,letter,index)//all为-a,letter为$1,为a,index=2 开始匹配的位置,从0开始    nodeName: function( elem, name ) {        return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();    },// args is for internal usage only    each: function( object, callback, args ) {        var name, i = 0,//有长度                length = object.length,//json对象的遍历                isObj = length === undefined || jQuery.isFunction( object );//args为真        if ( args ) {            if ( isObj ) {                for ( name in object ) {//举个例子:function add(b){console.log(b);}//$.each({'aaa':{ccc:1,'bbb':222}},add,['aaa']);//传递一个直接的参数,进行操作                    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        } else {            if ( isObj ) {                for ( name in object ) {//$.each([1,3,5,6],function(i,v){})                    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    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    makeArray: function( array, results ) {        var ret = results || [];        if ( array != null ) {// The window, strings (and functions) also have 'length'// Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930            var type = jQuery.type( array );            if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) {                push.call( ret, array );            } else {                jQuery.merge( ret, array );            }        }        return ret;    },    inArray: function( elem, array, i ) {        var len;        if ( array ) {            if ( indexOf ) {                return indexOf.call( array, elem, i );            }//首先执行 i < 0 ? Math.max( 0, len + i ) : i//如果不存在就从0开始,否则从当i<0时,len+i开始,>0直接从开始            len = array.length;            i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;            for ( ; i < len; i++ ) {//返回所在位置                if ( i in array && array[ i ] === elem ) {                    return i;                }            }        }        return -1;    },    merge: function( first, second ) {//jQuery.merge( ret, array );//传入的是init,和一个array        console.log(first);        console.log(second)        var i = first.length,                j = 0;//如果array是一个数组,在init的基础上再增加输入        if ( typeof second.length === "number" ) {            for ( var l = second.length; j < l; j++ ) {                first[ i++ ] = second[ j ];            }        } else {            while ( second[j] !== undefined ) {                first[ i++ ] = second[ j++ ];            }        }        first.length = i;//得到数组        return first;    },    grep: function( elems, callback, inv ) {//grep() 方法是按照某种条件来过滤数组        var ret = [], retVal;        inv = !!inv;// Go through the array, only saving the items// that pass the validator function//举个例子 var ccc=$.grep([1,2,4,'bb','cc'],function(v,i){return $.type(v)=='number'})//console.log(ccc);[1, 2, 4]//当最后参数设置为true是,到得到['bb','cc']        for ( var i = 0, length = elems.length; i < length; i++ ) {            retVal = !!callback( elems[ i ], i );            if ( inv !== retVal ) {                ret.push( elems[ i ] );            }        }        return ret;    },// arg is for internal usage only    map: function( elems, callback, arg ) {        var value, key, ret = [],                i = 0,                length = elems.length,// jquery objects are treated as arrays//jquery对象也被当做是数组,如$('div')                isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ;// Go through the array, translating each of the items to their        if ( isArray ) {            for ( ; i < length; i++ ) {                value = callback( elems[ i ], i, arg );                if ( value != null ) {                    ret[ ret.length ] = value;                }            }// Go through every key on the object,        } else {            for ( key in elems ) {                value = callback( elems[ key ], key, arg );                if ( value != null ) {                    ret[ ret.length ] = value;                }            }        }// Flatten any nested arrays        return ret.concat.apply( [], ret );    },// A global GUID counter for objects    guid: 1,// Bind a function to a context, optionally partially applying any// arguments.    proxy: function( fn, context ) {        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.        if ( !jQuery.isFunction( fn ) ) {            return undefined;        }// Simulated bind        var args = slice.call( arguments, 2 ),                proxy = function() {                    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        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 optionally be executed if it's a function    access: function( elems, fn, key, value, chainable, emptyGet, pass ) {        var exec,                bulk = key == null,                i = 0,                length = elems.length;// Sets many values        if ( key && typeof key === "object" ) {            for ( i in key ) {                jQuery.access( elems, fn, i, key[i], 1, emptyGet, value );            }            chainable = 1;// Sets one value        } else if ( value !== undefined ) {// Optionally, function values get executed if exec is true            exec = pass === undefined && jQuery.isFunction( value );            if ( bulk ) {// Bulk operations only iterate when executing function values                if ( exec ) {                    exec = fn;                    fn = function( elem, key, value ) {                        return exec.call( jQuery( elem ), value );                    };// Otherwise they run against the entire set                } else {                    fn.call( elems, value );                    fn = null;                }            }            if ( fn ) {                for (; i < length; i++ ) {                    fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );                }            }            chainable = 1;        }        return chainable ?                elems :// Gets                bulk ?                        fn.call( elems ) :                        length ? fn( elems[0], key ) : emptyGet;    },    now: function() {//返回当前的时间        return ( new Date() ).getTime();    },// Use of jQuery.browser is frowned upon.// More details: http://docs.jquery.com/Utilities/jQuery.browser    uaMatch: function( ua ) {        ua = ua.toLowerCase();        var match = rwebkit.exec( ua ) ||                ropera.exec( ua ) ||                rmsie.exec( ua ) ||                ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) ||                [];        return { browser: match[1] || "", version: match[2] || "0" };    },    sub: function() {        function jQuerySub( selector, context ) {            return new jQuerySub.fn.init( selector, context );        }        jQuery.extend( true, jQuerySub, this );        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: {}});// Populate the class2type mapjQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {    class2type[ "[object " + name + "]" ] = name.toLowerCase()});browserMatch = jQuery.uaMatch( userAgent );if ( browserMatch.browser ) {    jQuery.browser[ browserMatch.browser ] = true;    jQuery.browser.version = browserMatch.version;}// Deprecated, use jQuery.browser.webkit insteadif ( jQuery.browser.webkit ) {    jQuery.browser.safari = true;}

转载于:https://www.cnblogs.com/heyinwangchuan/p/6253773.html

你可能感兴趣的文章
react.js 多个组件集成示例
查看>>
用户故事驱动的敏捷开发 – 2. 创建backlog
查看>>
NLTK-Chapter8.4中符合语句规则的字串表-动态规划算法的解释
查看>>
AQS(AbstractQueuedSynchronizer)
查看>>
Ubuntu boot空间不足解决方法
查看>>
Linux基础命令---iostat显示设备状态
查看>>
java例程练习(多线程[join()方法])
查看>>
20155337 2016-2017-2 《Java程序设计》第三周学习总结
查看>>
覆盖equals时请遵守通用约定
查看>>
memcached的安装和使用
查看>>
inner join 各种连接 SQL语句
查看>>
经验人士的IOS APP设计心得
查看>>
teleport使用说明
查看>>
IdentityServer4 登录使用数据库
查看>>
从PDF中提取信息----PDFMiner
查看>>
极简Node教程-七天从小白变大神(一:你需要Express)
查看>>
Windows环境配置Apache+Mysql+PHP
查看>>
内网端口映射详解(花生壳)
查看>>
回调和回显有什么区别?
查看>>
业务逻辑与数据解耦+单元测试
查看>>