jQuery源码分析-03构造jQuery对象-工具函数

作者:nuysoft/高云 QQ:47214707 EMail:nuysoft@gmail.com
声明:本文为原创文章,如需转载,请注明来源并保留原文链接。
读读写写,不对的地方请告诉我,多多交流共同进步,本章的的PDF等本章写完了发布。
jQuery源码分析系列的目录请查看 http://nuysoft.iteye.com/blog/1177451,想系统的好好写写,目前还是从我感兴趣的部分开始,如果大家有对哪个模块感兴趣的,建议优先分析的,可以告诉我,一起学习。
3.4 其他静态工具函数


代码如下:

// 扩展工具函数
jQuery.extend({
// 释放$的 jQuery 控制权
// 许多 JavaScript 库使用 $ 作为函数或变量名,jQuery 也一样。
// 在 jQuery 中,$ 仅仅是 jQuery 的别名,因此即使不使用 $ 也能保证所有功能性。
// 假如我们需要使用 jQuery 之外的另一 JavaScript 库,我们可以通过调用 $.noConflict() 向该库返回控制权。
// 通过向该方法传递参数 true,我们可以将 $ 和 jQuery 的控制权都交还给另一JavaScript库。
noConflict: function( deep ) {
// 交出$的控制权
if ( window.$ === jQuery ) {
window.$ = _$;
}
// 交出jQuery的控制权
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
// 一个计数器,用于跟踪在ready事件出发前的等待次数
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
//
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事件处理函数队列
// 兼容不同浏览对绑定事件的区别
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回调函数
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之前触发onreadystatechange,可能慢一些但是对iframes更安全
document.attachEvent( "onreadystatechange", DOMContentLoaded );
// A fallback to window.onload, that will always work
// 注册window.onload回调函数
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";
},
// 是否数组
// 如果浏览器有内置的 Array.isArray 实现,就使用浏览器自身的实现方式,
// 否则将对象转为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 或 不是数字 或调用window.isNaN判断
return obj == null || !rdigit.test( obj ) || isNaN( obj );
},
// 获取对象的类型
type: function( obj ) {
// 通过核心API创建一个对象,不需要new关键字
// 普通函数不行
// 调用Object.prototype.toString方法,生成 "[object Xxx]"格式的字符串
// class2type[ "[object " + name + "]" ] = name.toLowerCase();
return obj == null ?
String( obj ) :
class2type[ toString.call(obj) ] || "object";
},
// 检查obj是否是一个纯粹的对象(通过"{}" 或 "new Object"创建的对象)
// 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分析与重构 http://www.jb51.net/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
// 必须是一个对象
// 因为在IE8中会抛出非法指针异常,必须检查constructor属性
// DOM节点和window对象,返回false
// obj不存在 或 非object类型 或 DOM节点 或 widnow对象,直接返回false
// 测试以下三中可能的情况:
// jQuery.type(obj) !== "object" 类型不是object,忽略
// obj.nodeType 认为DOM节点不是纯对象
// jQuery.isWindow( obj ) 认为window不是纯对象
if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
return false;
}
// Not own constructor property must be Object
// 测试constructor属性
// 具有构造函数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及不存在任何属性,认为是简单的纯对象
// 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;
},
// 抛出一个异常
error: function( msg ) {
throw msg;
},
// 解析JSON
// parseJSON把一个字符串变成JSON对象。
// 我们一般使用的是eval。parseJSON封装了这个操作,但是eval被当作了最后手段。
// 因为最新JavaScript标准中加入了JSON序列化和反序列化的API。
// 如果浏览器支持这个标准,则这两个API是在JS引擎中用Native Code实现的,效率肯定比eval高很多。
// 目前来看,Chrome和Firefox4都支持这个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函数也主要是标准API和IE的封装。
// 标准API是DOMParser对象。
// 而IE使用的是Microsoft.XMLDOM的 ActiveXObject对象。
parseXML: function( data , xml , tmp ) {
if ( window.DOMParser ) { // Standard 标准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;
},
// 无操作函数
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函数把一段脚本加载到全局context(window)中。
// IE中可以使用window.execScript。
// 其他浏览器 需要使用eval。
// 因为整个jQuery代码都是一整个匿名函数,所以当前context是jQuery,如果要将上下文设置为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 );
}
},
// 判断节点名称是否相同
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,
isObj = length === undefined || jQuery.isFunction( object );
// 如果有参数args,调用apply,上下文设置为当前遍历到的对象,参数使用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
// 没有参数args则调用,则调用call,上下文设置为当前遍历到的对象,参数设置为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方法,否则先过滤开头的空格,再过滤结尾的空格
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'
// 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
// 一大堆浏览器兼容性测试,真实蛋疼
var type = jQuery.type( array );
// 测试:有没有length属性、字符串、函数、正则
// 不是数组,连伪数组都不是
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 ) {
// 直接调用Array.prototype.indexOf
return indexOf.call( array, elem );
}
// 遍历数组,查找是否有完全相等的元素,并返回下标
// 循环的小技巧:把array.length存放到length变量中,可以减少一次作用域查找
for ( var i = 0, length = array.length; i < length; i++ ) {
if ( array[ i ] === elem ) {
return i;
}
}
// 如果返回-1,则表示不在数组中
return -1;
},
// 将数组second合并到数组first中
merge: function( first, second ) {
var i = first.length, //
j = 0;
// 如果second的length属性是Number类型,则把second当数组处理
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属性,因为first可能不是真正的数组
first.length = i;
return first;
},
// 过滤数组,返回新数组;callback返回true时保留;如果inv为true,callback返回false才会保留
grep: function( elems, callback, inv ) {
var ret = [], retVal;
inv = !!inv;
// Go through the array, only saving the items
// that pass the validator function
// 遍历数组,只保留通过验证函数callback的元素
for ( var i = 0, length = elems.length; i < length; i++ ) {
// 这里callback的参数列表为:value, index,与each的习惯一致
retVal = !!callback( elems[ i ], i );
// 是否反向选择
if ( inv !== retVal ) {
ret.push( elems[ i ] );
}
}
return ret;
},
// arg is for internal usage only
// 将数组或对象elems的元素/属性,转化成新的数组
map: function( elems, callback, arg ) {
var value, key, ret = [],
i = 0,
length = elems.length,
// jquery objects are treated as arrays
// 检测elems是否是(伪)数组
// 1. 将jQuery对象也当成数组处理
// 2. 检测length属性是否存在,length等于0,或第一个和最后一个元素是否存在,或jQuery.isArray返回true
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
// 遍历数组,对每一个元素调用callback,将返回值不为null的值,存入ret
if ( isArray ) {
for ( ; i < length; i++ ) {
// 执行callback,参数依次为value, index, arg
value = callback( elems[ i ], i, arg );
// 如果返回null,则忽略(无返回值的function会返回undefined)
if ( value != null ) {
ret[ ret.length ] = value;
}
}
// Go through every key on the object,
// 遍历对象,对每一个属性调用callback,将返回值不为null的值,存入ret
} else {
for ( key in elems ) {
// 执行callback,参数依次为value, key, arg
value = callback( elems[ key ], key, arg );
// 同上
if ( value != null ) {
ret[ ret.length ] = value;
}
}
}
// Flatten any nested arrays
// 使嵌套数组变平
// concat:
// 如果某一项为数组,那么添加其内容到末尾。
// 如果该项目不是数组,就将其作为单个的数组元素添加到数组的末尾。
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是字符串,设置上下文为fn,fn为fn[ context ]
// 即设置fn的context方法的上下文为fn(默认不是这样吗???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是否是可调用的(即函数),在文档说明中,会抛出一个TypeError,
// 但是这里仅返回undefined
if ( !jQuery.isFunction( fn ) ) {
return undefined;
}
// Simulated bind
var args = slice.call( arguments, 2 ), // 从参数列表中去掉fn,context
proxy = function() {
// 设置上下文为context和参数
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
// 统一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
// 多功能函数,读取或设置集合的属性值;值为函数时会被执行
// 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
// 如果有多个属性,则迭代
if ( typeof key === "object" ) {
for ( var k in key ) {
jQuery.access( elems, k, key[k], exec, fn, value );
}
return elems;
}
// Setting one attribute
// 只设置一个属性
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;
},
// 获取当前时间的便捷函数
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 一个只读的字符串,声明了浏览器用于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等)时,默认为""
// match[2] || "0"
// match[2]为false(空字符串、null、undefined、0等)时,默认为"0"
return { browser: match[1] || "", version: match[2] || "0" };
},
// 创建一个新的jQuery副本,副本的属性和方法可以被改变,但是不会影响原始的jQuery对象
// 有两种用法:
// 1. 覆盖jQuery的方法,而不破坏原始的方法
// 2.封装,避免命名空间冲突,可以用来开发jQuery插件
// 值得注意的是,jQuery.sub()函数并不提供真正的隔离,所有的属性、方法依然指向原始的jQuery
// 如果使用这个方法来开发插件,建议优先考虑jQuery UI widget工程
sub: function() {
function jQuerySub( selector, context ) {
return new jQuerySub.fn.init( selector, context );
}
jQuery.extend( true, jQuerySub, this ); // 深度拷贝,将jQuery的所有属性和方法拷贝到jQuerySub
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可能会移到一个插件中
browser: {}
});

(0)

相关推荐

  • 实例解析jQuery工具函数

    一.$.browser对象属性 属性列表 说明 webkit webkit相关浏览器则返回true,否则返回false,如google,傲游.    mozilla mozilla相关浏览器则返回true,否则返回false,如火狐 safari    safari相关浏览器则返回true,否则返回false,如safari opera   opera相关浏览器则返回true,否则返回false,如opera msie msie相关浏览器则返回true,否则返回false,如IE,360,搜狗

  • JQuery 操作Javascript对象和数组的工具函数小结

    JQuery操作非集合数组函数 $.trim(value) 这个函数很简单,从value中删除任何前导或尾随的空白字符.空白字符为任何匹配Javascript正则表达式\s的任何字符.包括空格.换页.换行.回车.tab.垂直指标符等. $.each(container, callback) 对container的每一项进行迭代,为每一项调用回调函数callback. container 可以是对象或数组.如果是js对象,则迭代其每个属性:如果是数组,则迭代其每个元素. callback 回调函数

  • 从零开始学习jQuery (九) jQuery工具函数

    一.摘要 本系列文章将带您进入jQuery的精彩世界, 其中有很多作者具体的使用经验和解决方案,  即使你会使用jQuery也能在阅读中发现些许秘籍. 我们经常要使用脚本处理各种业务逻辑, 最常见的就是数组和对象的操作. jQuery工具函数为我们操作对象和数组提供了便利条件. 二.前言 大部分人仅仅使用jQuery的选择器选择对象, 或者实现页面动画效果. 在处理业务逻辑时常常自己编写很多算法. 本文提醒各位jQuery也能提高我们操作对象和数组的效率. 并且可以将一些常用算法扩充到jQuer

  • jQuery 工具函数学习资料

    URL 字符串操作 数组和对象操作 测试操作 浏览器 1:URL操作: $.param(obj) 返回 :string: 说明:将jquery对象按照name/value 或者key/value序列化为URL参数,用&连接. 示例: var obj ={name:zh,age:20}; alert(jQuery.param(obj)); //alert "name=zh&age=20"; 2:字符串操作: jQuery.trim(str) 返回:string: 说明:去

  • JQuery工具函数汇总

    在jQuery中,工具函数是指直接依附于jQuery对象,针对jQuery对象本身定义的方法,即全局性的,我们统称为工具函数,或Utilites函数 主要作用于:字符串.数组.对象 API:工具函数 调用格式:   $.函数名()或jQuery.函数名() 字符串操作: $.trim():去除字符串左右两边的空格 数组和对象操作: $.each():遍历数组 $.each(array,function(index,value){}):array:数组变量,index:元素下标,从0开始,valu

  • jQuery源码分析-03构造jQuery对象-工具函数

    作者:nuysoft/高云 QQ:47214707 EMail:nuysoft@gmail.com 声明:本文为原创文章,如需转载,请注明来源并保留原文链接. 读读写写,不对的地方请告诉我,多多交流共同进步,本章的的PDF等本章写完了发布. jQuery源码分析系列的目录请查看 http://nuysoft.iteye.com/blog/1177451,想系统的好好写写,目前还是从我感兴趣的部分开始,如果大家有对哪个模块感兴趣的,建议优先分析的,可以告诉我,一起学习. 3.4 其他静态工具函数

  • jQuery源码分析-03构造jQuery对象-源码结构和核心函数

    作者:nuysoft/高云 QQ:47214707 EMail:nuysoft@gmail.com 毕竟是边读边写,不对的地方请告诉我,多多交流共同进步.本章还未写完,完了会提交PDF. 前记: 想系统的好好写写,但是会先从感兴趣的部分开始. 近期有读者把PDF传到了百度文库上,首先感谢转载和传播,但是据为已有并设置了挺高的财富值才能下载就不好了,以后我整理好了会传到文库上.请体谅一下. 3. 构造jQuery对象 3.1 源码结构 先看看总体结构,再做分解: 复制代码 代码如下: (funct

  • jQuery 源码分析笔记(6) jQuery.data

    data部分的代码从1381行开始.最开始的几行关键代码: 复制代码 代码如下: jQuery.extend({ // 存储数据的地方,关键实现核心 cache: { }, // 分配ID用的seed uuid: 0, // 为了区别不同的jQuery实例存储的数据,使用前缀+jQuery版本号+随机数作为Key expando: "jQuery" + (jQuery.fn.jquery + Math.random()).replace(/\D/g, ""), //

  • jQuery 源码分析笔记(5) jQuery.support

    其中jQuery.browser已经提供了根据UserAgent检测的浏览器信息.而jQuery.support 使用特性检测来检查浏览器的功能以及Bug. 和文档一样,首先说明一下,这个模块是很底层的代码,基本不需要在日常开发中使用,但是插件的开发者更需要.因为插件需要兼容各个浏览器.首先看一下 support模块提供了哪些浏览器特性的检测,以下结果是在Chrome 13 Dev下看到的结果.根据浏览器的不同,这里的成员可能会有变化.(PS:再次吐槽IE,大部分属性都是IE比较特别) ajax

  • jQuery源码分析之jQuery.fn.each与jQuery.each用法

    本文实例讲述了jQuery源码分析之jQuery.fn.each与jQuery.each用法.分享给大家供大家参考.具体分析如下: 先上例子,下面代码的作用是:对每个选中的div元素,都给它们添加一个red类 复制代码 代码如下: $('div').each(function(index, elem){       $(this).addClass('red'); } }); 上面用的的.each,即jQuery.fn.each,其内部是通过jQuery.each实现的 复制代码 代码如下: j

  • jQuery源码分析之Callbacks详解

    代码的本质突出顺序.有序这一概念,尤其在javascript--毕竟javascript是单线程引擎. javascript拥有函数式编程的特性,而又因为javascript单线程引擎,我们的函数总是需要有序的执行.优秀代码常常 把函数切割成各自的模块,然后在某一特定条件下执行,既然这些函数是有序的执行,那么我们为什么不编写一个统一管理的对象,来帮助我们管理这些函数--于是,Callbacks(回调函数)诞生. 什么是Callbacks javascript中充斥着函数编程,例如最简单的wind

  • php源码分析之DZX1.5字符串截断函数cutstr用法

    本文实例讲述了php源码分析之DZX1.5字符串截断函数cutstr用法.分享给大家供大家参考.具体分析如下: <?php /** * 函数来源DZX1.5,文件所在 /source/function/function_core.php */ define('CHARSET','UTF-8'); function cutstr($string, $length, $dot="...") { if(strlen($string)<=$length) { return $str

  • php源码分析之DZX1.5加密解密函数authcode用法

    本文实例讲述了php源码分析之DZX1.5加密解密函数authcode用法.分享给大家供大家参考.具体分析如下: <?php $authkey = ''; /** * @param string $string: 输入的需要加密(或解密)的明文(或密文) * @param string $operation: 'DECODE'或其它,其中默认表示解密,输入其它表示加密 * @param string $key: 加解密密钥 * @param int $expiry: 有效期 */ functio

  • jQuery源码分析-01总体架构分析

    1. 总体架构 1.1 自调用匿名函数 self-invoking anonymous function 打开jQuery源码,首先你会看到这样的代码结构: 复制代码 代码如下: (function( window, undefined ) { // jquery code })(window); 1. 这是一个自调用匿名函数.什么东东呢?在第一个括号内,创建一个匿名函数:第二个括号,立即执行 2. 为什么要创建这样一个"自调用匿名函数"呢? 通过定义一个匿名函数,创建了一个"

  • jQuery源码分析之init的详细介绍

    init 构造器 由于这个函数直接和 jQuery() 的参数有关,先来说下能接受什么样的参数. 源码中接受 3 个参数: init: function (selector, context, root) { ... } jQuery() ,空参数,这个会直接返回一个空的 jQuery 对象,return this. jQuery( selector [, context ] ) ,这是一个标准且常用法,selector 表示一个 css 选择器,这个选择器通常是一个字符串,#id 或者 .cl

随机推荐