jquery1.9.1汉化版,我自己翻译的,给些意见。

wohuifude123 2013-02-23 11:10:16
/*!
* jQuery JavaScript Library v1.9.1
* http://jquery.com/
*
* Includes Sizzle.js
* http://sizzlejs.com/
*
* Copyright 2005, 2012 jQuery Foundation, Inc. and other contributors
* Released under the MIT license
* http://jquery.org/license
*
* 日期: 2013年2月4日
* 翻译:刘建(毕业院校:家里蹲大学低能班)
* 联系邮箱:243376129@qq.com
* 原文地址:http://www.cnblogs.com/laonanren/archive/2013/02/14/2912145.html
* 翻译上的不足之处,希望大家能告诉我,我会尽量修改,本人才疏学浅,文化程度不高,希望大家多多包涵,我会努力改正。
*/
(function( window, undefined ) {
//不要做这个因为各自的应用程序包括ASP.NET查找
// the stack via arguments.caller.callee and Firefox dies if
//你尝试查找通过“精确使用”呼叫链接(#13335)
//支持:火狐浏览器 18+
//“精确使用”;
var
//deferred对象被使用在DOM(Document Object Model翻译:文档对象模型)准备之时
//deferred(延迟)对象:从jQuery 1.5.0版本开始引入的一个新功能
//在DOM准备好时调用
readyList,

//一个中心引用对于jQuery根文档
//对根jQuery对象的主要引用
rootjQuery,

//支持:IE9之前的版本
// For `typeof node.method` instead of `node.method !== undefined`
core_strundefined = typeof undefined,

// Use the correct document accordingly with window argument (sandbox)
document = window.document,//window文档赋值给变量document
location = window.location,

// Map over jQuery in case of overwrite(不确定,待修正,希望高人帮忙翻译一下)
//在jQuery上绘制写在上面的实例
//防止被覆盖
_jQuery = window.jQuery,

// Map over the $ in case of overwrite
_$ = window.$,
//将window正则表达式符号$赋值给变量_$
//[类]:成双类型
class2type = {},

//在贮存区被删除数据ID的列表,我们能够再用他们
core_deletedIds = [],

core_version = "1.9.1",

//保存一个参考给一些核心的方法
//为核心方法创建引用
core_concat = core_deletedIds.concat,
core_push = core_deletedIds.push,
core_slice = core_deletedIds.slice,
core_indexOf = core_deletedIds.indexOf,
core_toString = class2type.toString,
core_hasOwn = class2type.hasOwnProperty,
core_trim = core_version.trim,

//规定一个jQuery本地代码
//构建jQuery对象
jQuery = function( selector, context ) {
//jQuery对象是实际上初始化名为enhanced(提高的)构造器
//jQuery对象实际上只是增强的初始化构造方法
return new jQuery.fn.init( selector, context, rootjQuery );
},
/* 用来匹配数字的正则,匹配可选正负号、浮点型、整型、科学计数法
* 没有使用(?)来表示可选而是通过(|)来选择
* (?:\d*\.|)匹配浮点数时,|前的\d*\.可以匹配整数部分和小数点,小数部分由后面的\d+匹配
* 匹配整数时,|)可以保证匹配继续向下进行,整数由后面的\d+匹配,同样的\d+在匹配整型和浮点型时负责的匹配部分不同
* [eE][\-+]?\d+|)处理科学计数法的匹配,同样没有使用?表示可选
*/
core_pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,

//用于分开空格
core_rnotwhite = /\S+/g,
//查找非空白字符串
// Make sure we trim BOM and NBSP (here's looking at you, Safari 5.0 and IE)
rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
//\uFEFF:字节顺序标志
//一个简单途径用于检查HTML字符串
// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
// Strict HTML recognition (#11290: must start with <)
rquickExpr = /^(?:(<[\w\W]+>)[^>]*|#([\w-]*))$/,

//匹配一个独立的标签
rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/,

// JSON RegExp(JavaScript Object Notation:JavaScript对象标记法正则表达式)
rvalidchars = /^[\],:{}\s]*$/,
rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,
rvalidescape = /\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,
rvalidtokens = /"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g,

// Matches dashed string for camelizing
rmsPrefix = /^-ms-/,
rdashAlpha = /-([\da-z])/gi,
//以上为正则运算表达式各种形式,不太容易理解,尽量掌握。

//使用jQuery.cameCase(camel-case:骆驼事例标记法)作为replce()函数(替换函数)的回调函数
fcamelCase = function( all, letter ) {
return letter.toUpperCase();
},

//准备事件管理语句
completed = function( event ) {

// readyState === "complete" is good enough for us to call the dom ready in oldIE
if ( document.addEventListener || event.type === "load" || document.readyState === "complete" ) {
detach();
jQuery.ready();
}
},
//为DOM准备事件清理方法
detach = function() {
if ( document.addEventListener ) {
document.removeEventListener( "DOMContentLoaded", completed, false );
window.removeEventListener( "load", completed, false );

} else {
document.detachEvent( "onreadystatechange", completed );
window.detachEvent( "onload", completed );
}
};

jQuery.fn = jQuery.prototype = {
// The current version of jQuery being used
jquery: core_version,

constructor: jQuery,
init: function( selector, context, rootjQuery ) {
var match, elem;

//HANDLE(句柄):$(""), $(null), $(undefined), $(false)
if ( !selector ) {
return this;
}

//HTML字符串句柄
if ( typeof selector === "string" ) {//如果(选择器的类型等于字符串
if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
// Assume that strings that start and end with <> are HTML and skip the regex check
match = [ null, selector, null ];

} else {
match = rquickExpr.exec( selector );
}

// Match html or make sure no context is specified for #id
//匹配html或者确认对于#id没有环境是规定的
if ( match && (match[1] || !context) ) {

// HANDLE: $(html) -> $(array)
if ( match[1] ) {
context = context instanceof jQuery ? context[0] : context;

// 脚本向后兼容
jQuery.merge( this, jQuery.parseHTML(
match[1],
context && context.nodeType ? context.ownerDocument || context : document,
true
) );

//处理: $(html, props)
if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {
for ( match in context ) {
// Properties of context are called as methods if possible
//如果可能上下文的性质被访问
if ( jQuery.isFunction( this[ match ] ) ) {
this[ match ]( context[ match ] );

// ...and otherwise set as attributes
} else {
this.attr( match, context[ match ] );
}
}
}

return this;

// HANDLE: $(#id)
// 处理: $(#id)
} else {
elem = document.getElementById( match[2] );

// Check parentNode to catch when Blackberry 4.6 returns
//节点不再在文档中 #6963
if ( elem && elem.parentNode ) {
// Handle the case where IE and Opera return items
// 处理事件无论IE和Opera把项目返回到哪里
// by name instead of ID
// 用名字替代ID
if ( elem.id !== match[2] ) {
return rootjQuery.find( selector );
}

// Otherwise, we inject the element directly into the jQuery object
this.length = 1;
this[0] = elem;
}

this.context = document;
this.selector = selector;
return this;
}

// HANDLE: $(expr, $(...))
} else if ( !context || context.jquery ) {
return ( context || rootjQuery ).find( selector );

// HANDLE: $(expr, context)
// (which is just equivalent to: $(context).find(expr)
} else {
return this.constructor( context ).find( selector );
}

// HANDLE: $(DOMElement)
} else if ( selector.nodeType ) {
this.context = this[0] = selector;
this.length = 1;
return this;

// HANDLE: $(function)
// Shortcut for document ready
} else if ( jQuery.isFunction( selector ) ) {
return rootjQuery.ready( selector );
}

if ( selector.selector !== undefined ) {
this.selector = selector.selector;
this.context = selector.context;
}

return jQuery.makeArray( selector, this );
},

// Start with an empty selector
// 用一个空选择器开始
selector: "",

// The default length of a jQuery object is 0
length: 0,

// The number of elements contained in the matched element set
// 匹配事件集包含事件的数量
size: function() {
return this.length;
},

toArray: function() {
return core_slice.call( this );
},

// Get the Nth element in the matched element set OR
// Get the whole matched element set as a clean array
get: function( num ) {
return num == null ?

// Return a 'clean' array
this.toArray() :

// Return just the object
( num < 0 ? this[ this.length + num ] : this[ num ] );
},

// Take an array of elements and push it onto the stack
// (returning the new matched element set)
pushStack: function( elems ) {

// Build a new jQuery matched element set
var ret = jQuery.merge( this.constructor(), elems );

// Add the old object onto the stack (as a reference)
ret.prevObject = this;
ret.context = this.context;

// Return the newly-formed element set
return ret;
},

// Execute a callback for every element in the matched set.
// (You can seed the arguments with an array of args, but this is
// only used internally.)
each: function( callback, args ) {
return jQuery.each( this, callback, args );
},

ready: function( fn ) {
// Add the callback
// 增加回调函数
...全文
1855 41 打赏 收藏 转发到动态 举报
写回复
用AI写文章
41 条回复
切换为时间正序
请发表友善的回复…
发表回复
ez2dj_dl 2014-09-01
  • 打赏
  • 举报
回复
翻译也算一个学习方法
mengfk000 2014-09-01
  • 打赏
  • 举报
回复
好,顶,支持,威武,有希望了
M依然 2014-09-01
  • 打赏
  • 举报
回复
建议不要怎么干吸取了。。 没有任何实际意义。你能告诉我们 你花这么大的功夫收获咋样嘛。。。还有我很羡慕楼主这么有空。。
thy442030800 2013-10-14
  • 打赏
  • 举报
回复
今天才看到的这个贴,赶脚这样玩是不是没什么意思啊? 我也在看jquery1.9.1的源码,自己添加一些理解,比如:

//匿名自调用函数 (function(){//代码逻辑})();
(function( window, undefined ) {

......

    //undefied的类型是不与任何类型相等的, 与其他任何类型比较都将返回false. 所以这里才用typeof来比较
    //===和!==是全等和全不等, 意为无需转换类型直接比较, 结果相等或不相等
    // Support: IE<9
    // For `typeof node.method` instead of `node.method !== undefined`
    core_strundefined = typeof undefined,

......

//列举出Object和Array常用的prototype方法的引用, 访问时会方便+快一点
	// Save a reference to some core methods
	core_concat = core_deletedIds.concat,
	core_push = core_deletedIds.push,
	core_slice = core_deletedIds.slice,
	core_indexOf = core_deletedIds.indexOf,
	core_toString = class2type.toString,
	core_hasOwn = class2type.hasOwnProperty,
	core_trim = core_version.trim,

......

    // Used for matching numbers
    //此正则乍一看很是唬人, 仔细分析一下
    //[+-]? 匹配字符串前面会出现+号或-号,且次数为1次或0次。
    //(?:\d*\.|) 首先来说,这是一个分组,但是前面的?:指示将不自动名分分组也不捕获文本。\d*\.则是匹配出现0个或多个数字后跟一个.号,|是规则分割符,如果满足该条件则不进行后向匹配。
    //\d+ 匹配1个或多个数字
    //(?:[eE][+-]?\d+|) 分组情况同上,匹配科学计数法。一个大写或小写e,后跟0个或1个+号或-号,再跟1个或一个以上的数字。
	core_pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,

......

}(window);
绿色123 2013-08-25
  • 打赏
  • 举报
回复
纯粹的中文式翻译,用的百度翻译吧,好多地方都错的,我觉的还是看英文版的才有人家的深意,
river_t 2013-08-24
  • 打赏
  • 举报
回复
支持,支持中文的。楼主,well done! 什么时候整理一个完整的上载上来大家下载下来看更方便。
plzzz 2013-08-24
  • 打赏
  • 举报
回复
Fire handlers 不是触发监听函数么???
zhukan19640413 2013-07-23
  • 打赏
  • 举报
回复
支持,鼓励一下
wohuifude123 2013-07-23
  • 打赏
  • 举报
回复
这个帖子好真好久没看了,楼上你们太棒了。 我今天又回来看看。 楼主你太棒了
笃志近思 2013-07-01
  • 打赏
  • 举报
回复
很强!支持。。。。。
netyaksa 2013-07-01
  • 打赏
  • 举报
回复
太牛了,给个文件,让大家一起下载吧,
灬达果 2013-05-30
  • 打赏
  • 举报
回复
叼爆了!!!!!!!!
bloodynumen 2013-05-30
  • 打赏
  • 举报
回复
人才~呀~ 支持下
wohuifude123 2013-04-05
  • 打赏
  • 举报
回复
连接27楼,继续翻译。
jQuery.extend({

	Deferred: function( func ) {
		var tuples = [
				// action, add listener, listener list, final state
				// 动作、添加监听(我翻译为监听,那位前辈翻译为回调函数)、监听列表、最终状态
				// 以下添加了关于jQuery.Deferred的解释(感觉解释的很详细,所以就写了上来)
				// 原文是在jQuery1.8.2的源码上进行分析。此版本是1.9.1版本,与原文代码稍有一些变化,请注意下。
				// 摘自Lovesueee的博客文章:http://www.cnblogs.com/lovesueee/archive/2012/10/18/2730287.html
				// 数据元组集
				// 每个元组分别包含一些与当前deferred相关的信息: 
				// 分别是:触发回调函数列表执行(函数名),添加回调函数(函数名),
				// 回调函数列表(jQuery.Callbacks对象),deferred最终状态(第三组数据除外)
				// 总体而言,三个元组会有对应的三个callbacklist对应于doneList, failList, processList

				[ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ],
				[ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ],
				[ "notify", "progress", jQuery.Callbacks("memory") ]
			],
				// deferred的状态,分为三种:pending(初始状态), resolved(解决状态), rejected(拒绝状态)
			state = "pending",
				// promise对象,主要有两点作用:
				// 1. 在初始化deferred对象时,promise对象里的方法都会被extend到deferred中去,作为引用
				// 2. 那么,生成的deferred对象里必然引用了promise对象的promise方法,所以当调用deferred.promise()时,
				//    deferred对象会通过闭包返回promise对象,这就是所谓的受限制的deferred对象(用deferred2表示),因为相比之前,
				//    返回的deferred2不在拥有resolve(With), reject(With), 
				//    notify(With)这些能改变deferred对象状态并且执行callbacklist的方法了
			promise = {
				// 返回闭包里的内部state(外部只读)
				state: function() {
					return state;
				},
				// 同时在doneList和failList的list里添加回调函数(引用)
				// 那么不论deferred最终状态是resolved还是rejected, 回调函数都会被执行,这就是所谓的always
				always: function() {
					deferred.done( arguments ).fail( arguments );
					return this;
				},
				// jQuery.then()会创建一个新的受限制的deferred对象
				then: function( /* fnDone, fnFail, fnProgress */ ) {
					var fns = arguments;
					// 创建新的受限制的deferred对象(称作newDeferrred),并返回
					// 利用返回的deferred对象就可以做很多事了,你懂的
					return jQuery.Deferred(function( newDefer ) {
						jQuery.each( tuples, function( i, tuple ) {
							var action = tuple[ 0 ],
								fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];
							// deferred[ done | fail | progress ] for forwarding actions to newDefer
							// 此行是翻译:为了将来关于新延期的行动,延期[ 被做 | 失败 | 进行 ] defer这里翻译为:延期
							// 分别为deferred的三个callbacklist添加回调函数,根据fn的是否是函数,分为两种情况:
// 1.不是函数的情况(如值为undefined或者null等),直接链接到newDeferred的resolve(reject,notify)方法,也就是说
//   newDeferrred的执行依赖外层的调用者deferred的状态或者说是执行动作(resolve还是reject或者是notify)
//   此时deferred.then()相当于将自己的callbacklist和newDeferred的callbacklist连接起来了,故可以在newDeferred
//   中大做文章
// 2.是函数的情况,根据返回值(称作returnReferred)是否是deferred对象,又可以分为两种情况:
//   2.1 返回值是deferred对象,那么在returnReferred对象的三个回调函数列表中添加newDeferred的resolve(reject,notify)方法
//       也就是说newDeferrred的执行依赖returnDeferred的状态
//   2.2 返回值不是deferred对象,那么将返回值returned作为newDeferred的参数并将从外层deferred那边的上下文环境作为newDeferred
//       的执行上下文,然后执行对应的回调函数列表,此时newDeferrred的执行依赖外层的调用者deferred的状态
							deferred[ tuple[1] ](function() {
								var returned = fn && fn.apply( this, arguments );
								if ( returned && jQuery.isFunction( returned.promise ) ) {
									returned.promise()
										.done( newDefer.resolve )
										.fail( newDefer.reject )
										.progress( newDefer.notify );
								} else {
									newDefer[ action + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );
								}
							});
						});
						fns = null;
					}).promise();
				},
				// Get a promise for this deferred
				// 获得这次延期的许可
				// If obj is provided, the promise aspect is added to the object
				// 如果对象被提供,允许的方面被添加到对象
				promise: function( obj ) {
					return obj != null ? jQuery.extend( obj, promise ) : promise;
				}
			},
			// 实际返回的deferred对象
			deferred = {};

		// Keep pipe for back-compat
		// 此行是翻译:保持pipe对于back-compat(这两个单词暂时不会翻译)
		// pipe和then引用同一个函数,所以功能是一样的
		// 只不过通常的用法是:会用pipe进行filter操作
		promise.pipe = promise.then;

		// Add list-specific methods
		// 此行是翻译:添加特性列表方法
		// 通过上面定义的数据元组集来扩展一些方法
		jQuery.each( tuples, function( i, tuple ) {
			var list = tuple[ 2 ],
				stateString = tuple[ 3 ];

			// promise[ done | fail | progress ] = list.add
			// 此行是翻译:允许[ 被做 | 失败 | 进行 ] = 添加列表
			// 给上面的promise对象添加done,fail,process方法
			// 这三个方法分别引用三个不同jQuery.Callbacks对象的add方法(不是同一个引用),
			// 那么这三个方法的用途就是向各自的回调函数列表list(各自闭包中)中添加回调函数,互不干扰
			promise[ tuple[1] ] = list.add;

			// Handle state
			// 此行是翻译:句柄状态
			// 通过stateString有值这个条件,预先向doneList,failList中的list添加三个回调函数
			// doneList : [changeState, failList.disable, processList.lock]
			// failList : [changeState, doneList.disable, processList.lock]
			// changeState 指的是下面首先添加的一个改变deferred对象的匿名函数
			// 可以看的出: 
			//不论deferred对象最终是resolve(还是reject),在首先改变对象状态之后,都会disable另一个函数列表failList(或者doneList)
			// 然后lock processList保持其状态,最后执行剩下的之前done(或者fail)进来的回调函数
			// 当然了,上述情况processList除外
			if ( stateString ) {
				list.add(function() {
					// state = [ resolved | rejected ]
					// 状态 = 【被决定的| 被拒绝的】
					state = stateString;

				// [ reject_list | resolve_list ].disable; progress_list.lock
				// [ 拒绝列表 | 决定列表 ].disable;; 进行列表.lock
				}, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
			}

			// deferred[ resolve | reject | notify ]
			// 此行是翻译:延期【决定|拒绝|通知】
			// 给deferred对象添加resolve(With), reject(With), notify(With)方法
			// 这三个方法分别引用三个不同jQuery.Callbacks对象的fire方法(不是同一个引用),
			// 那么这三个方法的用途就是执行各自的回调函数列表,互不干扰
			deferred[ tuple[0] ] = function() {
				deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments );
				return this;
			};
			deferred[ tuple[0] + "With" ] = list.fireWith;
		});

		// Make the deferred a promise
		// 此行是翻译:给延期一个允许
		// 将上面的promise对象extend进deferred中
		promise.promise( deferred );

		// Call given func if any
		// 此行是翻译:调用任何给定的函数
		// 如果调用jQuery.Deferred(func)指定了参数,那么调用func并设置func的上下文和参数均为deferred
		// 在jQuery.then()中有用到这一点
		if ( func ) {
			func.call( deferred, deferred );
		}

		// All done!
		// 此行是翻译:全都做完了
		// 返回最终的deferred对象
		return deferred;
	},

	// Deferred helper
	// 此行是翻译:延期帮助
	// 参数:一个(或多个)deferred对象(或其他)
	// 当传入的所有deferred对象都resolve或者reject了,执行when()创建的deferred对象
	// (称之为whenDeferred)对应的回调函数列表(非deferred对象被认为是resolve了)

	when: function( subordinate /* , ..., subordinateN */ ) {
		var i = 0,
			// 首先将arguments伪数组转换为真正的数组
			resolveValues = core_slice.call( arguments ),
			length = resolveValues.length,

			// the count of uncompleted subordinates
			// 此行是翻译:未完成下级的数量
			// 1. 在参数个数等于1的情况下:
			//   1.1 如果参数是deferred对象,那么remaining = length, 这是remaining就是1嘛
			//   1.2 否则remaining为0
			// 2. 在参数不等于1(即等于0或者大于1)的情况:remaining = length
			remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,

			// the master Deferred. If resolveValues consist of only a single Deferred, just use that.
			// 此行是翻译:主延迟。如果resolvevalues由仅有的一个单独延期组成,那么就使用那个。
			// 到这里就可以知道:如果参数个数仅为1个,并且是deferred对象,那么就无需再生成deferred对象
			deferred = remaining === 1 ? subordinate : jQuery.Deferred(),

			// Update function for both resolve and progress values
			// 此行是翻译:为了决定值和进行值,更新函数
			updateFunc = function( i, contexts, values ) {
				// 这里返回一个函数作为一个callback完全是为了创建一个闭包,主要是为了保持i的值
				return function( value ) {
					// 保存各个deferred执行的上下文,也就是说之后whenDeferred的回调函数的上下文就是一个数组
					contexts[ i ] = this;
					// 保存各个deferred执行时的参数,之后传递给whenDeferred的回调函数
					// 此时values的值有原先的jQuery.when()传进来的参数变为各个deferred执行回调时的参数了,也就是说覆盖了
					values[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value;
					if( values === progressValues ) {
						deferred.notifyWith( contexts, values );
					} else if ( !( --remaining ) ) {
						// 时机成熟,即所有延迟都resolve,执行whenDeferred的回调函数
						deferred.resolveWith( contexts, values );
					}
				};
			},

			progressValues, progressContexts, resolveContexts;

		// add listeners to Deferred subordinates; treat others as resolved
		// 此行是翻译:给延迟下级增加监听; 处理其他的作为被决定的
		// 如果参数个数大于1,那么就是说有可能存在多个deferred对象
		// 这时需要一些条件判断以保证是所有的deferred对象都resolve了,再执行whenDeferred的resolve
		// 或者当有一个deferred对象reject了,whenDeferred的reject
		if ( length > 1 ) {
			progressValues = new Array( length );
			progressContexts = new Array( length );
			resolveContexts = new Array( length );
			for ( ; i < length; i++ ) {
				// 如果是deferred对象
				if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
					// 给每个参数(deferred对象)添加最后的回调,用来检查此时的状态
					resolveValues[ i ].promise()
						// 用于当每一个deferred对象resolve回来,用updateFunc返回的函数检查此时其他deferred对象的状态
						// (即此时remaining是否等于0了)
						// 如果等于0,则执行whenDeferred的resolve,否则继续等待
						.done( updateFunc( i, resolveContexts, resolveValues ) )
						// 如果有一个deferred对象reject,whenDeferred将执行reject
						.fail( deferred.reject )
						.progress( updateFunc( i, progressContexts, progressValues ) );
						// 如果不是deferred对象,直接--remaining,视为resolve
				} else {
					--remaining;
				}
			}
		}

		// if we're not waiting on anything, resolve the master
		// 此行是翻译:如果我们不是正在等待什么,解决主延迟
		// 如果此时remaining就等与0了,表示没有什么延迟需要等待,那么立即之行whenDeferred的resolveWith
		// 此时resolveContexts为undefined, 这就意味这上下文将为全局的window
		if ( !remaining ) {
			deferred.resolveWith( resolveContexts, resolveValues );
		}
		// 返回受限制的deferred对象
		return deferred.promise();
	}
});//那位Lovesueee前辈的解释至此结束。
wohuifude123 2013-04-05
  • 打赏
  • 举报
回复
连接26楼,继续翻译
/*
 * Create a callback list using the following parameters:
 * 创建一个回调列表,使用一下参数:
 *	options: an optional list of space-separated options that will change how
 *			the callback list behaves or a more traditional option object
 *  选项:一个带有空间分割的可选择列表,将会改变回调列表行为或者一个传统的选项对象
 * By default a callback list will act like an event callback list and can be
 * "fired" multiple times.
 * 默认情况下,一个回调列表会采取一个类似事件回调列表的行为,并且能够多次"fired"(fired这里暂时译为:被炒鱿鱼)
 * Possible options:
 * 可能的选项:
 *	once:			will ensure the callback list can only be fired once (like a Deferred)
 *  一次:          将确保回调列表只能发生一次,例如一个延期(fire在这文档大量出现,意思不同,真的不好翻译)
 *	memory:			will keep track of previous values and will call any callback added
 *					after the list has been fired right away with the latest "memorized"
 *					values (like a Deferred)
 *  内存:          将持续监测以前的值,并且将调用任何被添加的回调
 *                  在立刻用最后被记忆的值(比如一个延期)清理列表之后
 *	unique:			will ensure a callback can only be added once (no duplicate in the list)
 *  唯一:          将确保一个回调仅能被添加一次(在列表中没有副本)
 *	stopOnFalse:	interrupt callings when a callback returns false
 *  发生错误停止:  当一个回调返回错误时,中断调用
 */
jQuery.Callbacks = function( options ) {

	// Convert options from String-formatted to Object-formatted if needed
	// 如果需要,转换选项从字符串格式到对象格式。
	// (we check in cache first)
	// (我们首先检测存储器)
	// Cache:高速缓冲存储器
	// 借用以下文章的一些注释,要不下面的一堆fire我就彻底无法解释了。
	// 文章地址:http://www.cnblogs.com/littledu/articles/2811728.html
	// 关于下面options的解释:这里设计为一个对象,这一步就是先判断下options缓存里有没这个对象存在,有直接拿来用,
	// 没有则通过createOptions方法将传过来的字符串转化为一个对象,对象形式如下: 
	options = typeof options === "string" ?
		( optionsCache[ options ] || createOptions( options ) ) :
		jQuery.extend( {}, options );

	var // Flag to know if list is currently firing(标记知道如果列表是firing,这里的firing是下面的一个变量)
		firing,
		// Last fire value (for non-forgettable lists)最后fire的值(非遗忘列表)
		memory,
		// Flag to know if list was already fired(标记知道如果列表是fired,这里的fired是下面的一个变量)
		fired,
		// End of the loop when firing(当是这个firing时,结束循环)
		firingLength,
		// Index of currently firing callback (modified by remove if needed)当前firing回调的索引(如果需要删除修改)
		firingIndex,
		// First callback to fire (used internally by add and fireWith)
		// 对于fire的第一个回调(内部使用添加或者解雇)
		firingStart,
		// Actual callback list
		// 现行的回调列表
		list = [],
		// Stack of fire calls for repeatable lists
		// 在可重复的列表中,跟踪fire调用
		stack = !options.once && [],
		// Fire callbacks
		// Fire回调
		fire = function( data ) {
			memory = options.memory && data; //当$.Callbacks('memory')时,保存data,data为数组[context,args] 
			fired = true; //表示已经执行,用于表示队列里的回调已经执行过一次 
			firingIndex = firingStart || 0; //执行队列的下标,相当于普通循环的i,当$.Callbacks('memory')时,需设置firingIndex 
			firingStart = 0; //重置队列起始值 
			firingLength = list.length; //保存队列的长度 
			firing = true; //标示正在执行中 
			for ( ; list && firingIndex < firingLength; firingIndex++ ) {
			// 遍历回调数组,执行每一个回调,当回调返回false且有传入stopOnFalse时,
			// 也就是$.Callbacks('stopOnFalse'),中止后面回调的执行。 
				if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {
					memory = false; // To prevent further calls using add阻止更远的调用使用添加
					break;
				}
			}
			firing = false; //函数执行完后,将执行中的标示设为false 
			if ( list ) {
				if ( stack ) { //执行完回调后,看一下stack是否有回调,如果有拿出来执行 
					if ( stack.length ) {
						fire( stack.shift() );
					}
				} else if ( memory ) {
					list = [];
				} else {
					self.disable();
				}
			}
		},
		// Actual Callbacks object
		// 现在的回调对象
		self = {
			// Add a callback or a collection of callbacks to the list
			// 给列表增加回调或者一个回调的集合
			add: function() {
				if ( list ) {
					// First, we save the current length
					// 首先,我们保存现在的长度
					var start = list.length;
					(function add( args ) {
						jQuery.each( args, function( _, arg ) {
							var type = jQuery.type( arg );
							if ( type === "function" ) {
								if ( !options.unique || !self.has( arg ) ) {
									list.push( arg );
								}
							} else if ( arg && arg.length && type !== "string" ) {
								// Inspect recursively
								// 递归观测
								add( arg );
							}
						});
					})( arguments );
					// Do we need to add the callbacks to the
					// current firing batch?
					// 我们需要给当前的firing堆中添加回调吗?
					if ( firing ) {
						firingLength = list.length;
					// With memory, if we're not firing then
					// we should call right away
					// 使用内容,如果我们不是firing,那么我们应该马上调用
					} else if ( memory ) {
						firingStart = start;
						fire( memory );
					}
				}
				return this;
			},
			// Remove a callback from the list
			// 从列表冲移除一个回调
			remove: function() {
				if ( list ) {
					jQuery.each( arguments, function( _, arg ) {
						var index;
						while( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
							list.splice( index, 1 );
							// Handle firing indexes
							// 管理firing索引
							if ( firing ) {
								if ( index <= firingLength ) {
									firingLength--;
								}
								if ( index <= firingIndex ) {
									firingIndex--;
								}
							}
						}
					});
				}
				return this;
			},
			// Check if a given callback is in the list.
			// 检测给定的回调是否在列表中
			// If no argument is given, return whether or not list has callbacks attached.
			// 如果什么参数也没给,无论列表有没有回调参与都返回
			has: function( fn ) {
				return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length );
			},
			// Remove all callbacks from the list
			// 从列表中移除所有的回调
			empty: function() {
				list = [];
				return this;
			},
			// Have the list do nothing anymore
			// 列表消失了
			disable: function() {
				list = stack = memory = undefined;
				return this;
			},
			// Is it disabled?
			// 它是禁用的吗?
			disabled: function() {
				return !list;
			},
			// Lock the list in its current state
			// 锁定列表,保持它当前的状态
			lock: function() {
				stack = undefined;
				if ( !memory ) {
					self.disable();
				}
				return this;
			},
			// Is it locked?
			// 它被锁住了吗?
			locked: function() {
				return !stack;
			},
			// Call all callbacks with the given context and arguments
			// 用给定的内容和参数调用所有的回调
			fireWith: function( context, args ) {
				args = args || [];
				args = [ context, args.slice ? args.slice() : args ];
				if ( list && ( !fired || stack ) ) {
					if ( firing ) {
						stack.push( args );
					} else {
						fire( args );
					}
				}
				return this;
			},
			// Call all the callbacks with the given arguments
			// 用给定的参数调用所有的回调
			fire: function() {
				self.fireWith( this, arguments );
				return this;
			},
			// To know if the callbacks have already been called at least once
			// 为了知道回调是否已经被调用了至少一次
			fired: function() {
				return !!fired;
			}
		};

	return self;
};
寂寞的孩子 2013-04-04
  • 打赏
  • 举报
回复
连接25楼,继续翻译
map: function( elems, callback, arg ) {
		var value,
			i = 0,
			length = elems.length,
			isArray = isArraylike( elems ),
			ret = [];
		// 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 ( i in elems ) {
				value = callback( elems[ i ], i, arg );

				if ( value != null ) {
					ret[ ret.length ] = value;
				}
			}
		}
		// Flatten any nested arrays
		// 拼接任意嵌套数组
		return core_concat.apply( [], ret );
	},

	// A global GUID counter for objects
	// 一个关于对象的全局GUID计数器
	// GUID:是Globally Unique Identifier(全局唯一标识符)的缩写
	guid: 1,

	// Bind a function to a context, optionally partially applying any
	// arguments.
	// 函数绑定到上下内容,任意地、部分地应用任何参数
	proxy: function( fn, context ) {
		var args, proxy, tmp;

		if ( typeof context === "string" ) {
			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.
		// 快速检查,判断目标是否可访问,在规范中,这将引发一个TypeError(类型错误),我们将仅返回未定义的。
		if ( !jQuery.isFunction( fn ) ) {
			return undefined;
		}

		// Simulated bind
		// 模拟绑定
		args = core_slice.call( arguments, 2 );
		proxy = function() {
			return fn.apply( context || this, args.concat( core_slice.call( arguments ) ) );
		};

		// Set the guid of unique handler to the same of original handler, so it can be removed
		// 把guid唯一的处理程序设置成语最初的处理程序相同,以便它能被删除
		proxy.guid = fn.guid = fn.guid || jQuery.guid++;

		return proxy;
	},

	// Multifunctional method to get and set values of a collection
	// 多种函数方法得到和设置一个集合的值
	// The value/s can optionally be executed if it's a function
	// 如果它是一个函数,单个或多个数值可以有选择的被执行。
	access: function( elems, fn, key, value, chainable, emptyGet, raw ) {
		var i = 0,
			length = elems.length,
			bulk = key == null;

		// Sets many values
		// 设置很多值
		if ( jQuery.type( key ) === "object" ) {
			chainable = true;
			for ( i in key ) {
				jQuery.access( elems, fn, i, key[i], true, emptyGet, raw );
			}

		// Sets one value
		// 设置一个值
		} else if ( value !== undefined ) {
			chainable = true;

			if ( !jQuery.isFunction( value ) ) {
				raw = true;
			}

			if ( bulk ) {
				// Bulk operations run against the entire set
				// 整体设置之前,选项批量运行。
				if ( raw ) {
					fn.call( elems, value );
					fn = null;

				// ...except when executing function values
				// ...除了当执行函数值时
				} else {
					bulk = fn;
					fn = function( elem, key, value ) {
						return bulk.call( jQuery( elem ), value );
					};
				}
			}

			if ( fn ) {
				for ( ; i < length; i++ ) {
					fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );
				}
			}
		}

		return chainable ?
			elems :

			// Gets
			// 得到(这里翻译估计不准确)
			bulk ?
				fn.call( elems ) :
				length ? fn( elems[0], key ) : emptyGet;
	},

	now: function() {
		return ( new Date() ).getTime();
	}
});

jQuery.ready.promise = function( obj ) {
	if ( !readyList ) {

		readyList = jQuery.Deferred();

		// Catch cases where $(document).ready() is called after the browser event has already occurred.
		// 在浏览器的事件已经发生后,捕捉$(document).ready()被访问的事例
		// we once tried to use readyState "interactive" here, but it caused issues like the one
		// 我们这里曾经尝试使用readyState "interactive"(相互影响),不是它引起了问题类似ChrisS发现的
		// discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15
		// 问题网址:http://bugs.jquery.com/ticket/12282#comment:15
		//readyState:HTTP请求的状态。属性的值从0开始,直到接收到完整的HTTP响应,这个值增加到4。
		if ( document.readyState === "complete" ) {
			// Handle it asynchronously to allow scripts the opportunity to delay ready
			// 异步处理,为了允许脚本有机会做延迟准备
			setTimeout( jQuery.ready );

		// Standards-based browsers support DOMContentLoaded
		// 基于标准的浏览器都支持DOMContentLoaded
		} else if ( document.addEventListener ) {
			// Use the handy event callback
			// 使用方便的事件回调
			document.addEventListener( "DOMContentLoaded", completed, false );

			// A fallback to window.onload, that will always work
			window.addEventListener( "load", completed, false );

		// If IE event model is used
		// 如果IE时间模块被使用
		} else {
			// Ensure firing before onload, maybe late but safe also for iframes
			// 在onload(暂时译为:加载)前确保解雇,也许迟了,但是对于内联框架也是安全的
			// iframe:元素会创建包含另外一个文档的内联框架(即行内框架)
			// 在 HTML 4.1 Strict DTD 和 XHTML 1.0 Strict DTD 中,不支持 iframe 元素。
			document.attachEvent( "onreadystatechange", completed );

			// A fallback to window.onload, that will always work
			// 对于window.onload,fallback(暂时译为:回退)将总会运行
			window.attachEvent( "onload", completed );

			// If IE and not a frame
			// 如果是IE并且不是一个框架
			// 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
							// 使用Diego Perini的诀窍
							// Diego Perini:本人才疏学浅,不知道此人是谁,不过在这里提起这人,想来这人也不简单
							// Google找到相关资料;JSMentors(JS顾问?)Diego Perini 网址:http://jsmentors.com/Diego-Perini.html
							// http://javascript.nwbox.com/IEContentLoaded/
							// 上面这个地址是此人个人主页上的一篇文章:讲的是IE方面的内容
							top.doScroll("left");
						} catch(e) {
							return setTimeout( doScrollCheck, 50 );
						}

						// detach all dom ready events
						// 断开所有DOM准备事件
						detach();

						// and execute any waiting functions
						// 并且执行任何等待的函数
						jQuery.ready();
					}
				})();
			}
		}
	}
	return readyList.promise( obj );
};

// Populate the class2type map
// 填充class2type地图
// class2type:不知道怎么解释
jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
	class2type[ "[object " + name + "]" ] = name.toLowerCase();
});

function isArraylike( obj ) {
	var length = obj.length,
		type = jQuery.type( obj );

	if ( jQuery.isWindow( obj ) ) {
		return false;
	}

	if ( obj.nodeType === 1 && length ) {
		return true;
	}

	return type === "array" || type !== "function" &&
		( length === 0 ||
		typeof length === "number" && length > 0 && ( length - 1 ) in obj );
}
// 上面这个isArraylike(obj)最后的return非常值得一看,小弟也看了很多代码,这么长的return确实没见过,而且还发现了好多不懂之处。
/*
来自(functionsub)前辈的解释,原样照搬。
return type === "array" || type !== "function" &&
        ( length === 0 ||
        typeof length === "number" && length > 0 && ( length - 1 ) in obj );
若type==='array'直接返回true
若type!=='array'的话,如果type!=='function'为true的话开始判断括号里的内容,否则整体返回false
括号里的内容如果length===0为true若括号里整体为true,整体返回true
若length===0为false,判断typeof length==='number',如果为flase,整体返回false
如果typeof length==='number',如果为true,判断length>0,如果为false,整体返回false
如果length>0为true,判断( length - 1 ) in obj,这话的意思就是如果是类数组的对象,
其结构肯定是{0:'aaa',1:'bbb',length:2}这样的key值为数字的,所以如果是类数组对象,判断在obj里是否能找到length-1这样的key,
如果找到,整体返回true,否则整体返回false
in就是判断一个key是否在一个obj里。比如var obj = {a:'111'},'a' in obj为true,'b' in obj为false
*/
// All jQuery objects should point back to these
// 所有的jQuery对象应该指向这些
rootjQuery = jQuery(document);
// String to Object options format cache
// 字符串对象选择缓存形式
var optionsCache = {};
// Convert String-formatted options into Object-formatted ones and store in cache
// 把字符串格式的选项转换为对象格式的选项,并且存储在缓存中。
function createOptions( options ) {
	var object = optionsCache[ options ] = {};
	jQuery.each( options.match( core_rnotwhite ) || [], function( _, flag ) {
		object[ flag ] = true;
	});
	return object;
}
此号id【u010156773】防忘
寂寞的孩子 2013-04-04
  • 打赏
  • 举报
回复
连接24楼,继续翻译
globalEval: function( data ) {
		if ( data && jQuery.trim( data ) ) {
			// We use execScript on Internet Explorer
			// 我们使用execScript函数在IE浏览器
			// eval() 与 window.execScript()作用基本相同
			// 说一点这两个区别: 在FireFox下window.execScript()函数不能运行,而eval()在两个浏览器下都能正常运行
			// eval的作用:把一段字符串传递给JS解析器,由Javascript解析器将这段字符串解析成Javascript
			// We use an anonymous function so that context is window
			// 我们使用一个匿名函数为了内容在window
			// rather than jQuery in Firefox
			// 相当于jQuery在Firefox(火狐浏览器)
			( window.execScript || function( data ) {
				window[ "eval" ].call( window, data );
			} )( data );
		}
	},

	// Convert dashed to camelCase; used by the css and data modules
	// 迅速转换为“骆驼拼写法”;使用CSS和数据模块
	// 骆驼拼写法:依靠单词的大小写拼写一个复合词的做法,比如比如,backColor(背景色)
	// 这种拼写法在正规的英语中是不允许的,但是在编程语言和商业活动中却大量使用。
    // 比如,sony公司的畅销游戏机PlayStation,play和station两个词的词首字母都是大写的。
    // 这样做的好处是可以用一连串的描述性单词来表述一个新的含义——因为中间没有空格,可以被视为一个新词(组),而不是一个短语。  
	// Microsoft forgot to hump their vendor prefix (#9572)
	// 微软忘记驼峰他们的供应商前缀(#9572)
	camelCase: function( string ) {
		return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
	},

	nodeName: function( elem, name ) {
		return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
	},
	// args is for internal usage only
	// args(暂时译为:参数列表)仅供内部使用
	each: function( obj, callback, args ) {
		var value,
			i = 0,
			length = obj.length,
			isArray = isArraylike( obj );

		if ( args ) {
			if ( isArray ) {
				for ( ; i < length; i++ ) {
					value = callback.apply( obj[ i ], args );

					if ( value === false ) {
						break;
					}
				}
			} else {
				for ( i in obj ) {
					value = callback.apply( obj[ i ], args );

					if ( value === false ) {
						break;
					}
				}
			}

		//一个特殊的,快速的,实例用于每个大部分普通应用
		} else {
			if ( isArray ) {
				for ( ; i < length; i++ ) {
					value = callback.call( obj[ i ], i, obj[ i ] );

					if ( value === false ) {
						break;
					}
				}
			} else {
				for ( i in obj ) {
					value = callback.call( obj[ i ], i, obj[ i ] );

					if ( value === false ) {
						break;
					}
				}
			}
		}

		return obj;
	},
	// Use native String.trim function wherever possible
	// 在任何可能的地方,使用本地的String.trim函数
	trim: core_trim && !core_trim.call("\uFEFF\xA0") ?
		function( text ) {
			return text == null ?
				"" :
				core_trim.call( text );
		} :
		// Otherwise use our own trimming functionality
		// 否则使用我们自己的微调功能
		function( text ) {
			return text == null ?
				"" :
				( text + "" ).replace( rtrim, "" );
		},
	// results is for internal usage only
	// 结果仅供内部使用
	makeArray: function( arr, results ) {
		var ret = results || [];

		if ( arr != null ) {
			if ( isArraylike( Object(arr) ) ) {
				jQuery.merge( ret,
					typeof arr === "string" ?
					[ arr ] : arr
				);
			} else {
				core_push.call( ret, arr );
			}
		}

		return ret;
	},

	inArray: function( elem, arr, i ) {
		var len;

		if ( arr ) {
			if ( core_indexOf ) {
				return core_indexOf.call( arr, elem, i );
			}

			len = arr.length;
			i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;

			for ( ; i < len; i++ ) {
				// Skip accessing in sparse arrays
				// 跳过访问稀少数组
				if ( i in arr && arr[ i ] === elem ) {
					return i;
				}
			}
		}

		return -1;
	},

	merge: function( first, second ) {
		var l = second.length,
			i = first.length,
			j = 0;

		if ( typeof l === "number" ) {
			for ( ; 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 ) {
		var retVal,
			ret = [],
			i = 0,
			length = elems.length;
		inv = !!inv;
		// Go through the array, only saving the items that pass the validator function
		// 通过数组,仅保留通过校验函数的项目
		for ( ; i < length; i++ ) {
			retVal = !!callback( elems[ i ], i );
			if ( inv !== retVal ) {
				ret.push( elems[ i ] );
			}
		}

		return ret;
	},
	// arg is for internal usage only
	// arg仅供内部使用
此号id【0u010156773】防忘
wohuifude123 2013-04-03
  • 打赏
  • 举报
回复
连接一楼,接着翻译
jQuery.ready.promise().done( fn );

		return this;
	},

	slice: function() {
		return this.pushStack( core_slice.apply( this, arguments ) );
	},

	first: function() {
		return this.eq( 0 );
	},

	last: function() {
		return this.eq( -1 );
	},

	eq: function( i ) {
		var len = this.length,
			j = +i + ( i < 0 ? len : 0 );
		return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );
	},

	map: function( callback ) {
		return this.pushStack( jQuery.map(this, function( elem, i ) {
			return callback.call( elem, i, elem );
		}));
	},

	end: function() {
		return this.prevObject || this.constructor(null);
	},

	// For internal use only.
	// 只是为了内部使用
	// Behaves like an Array's method, not like a jQuery method.
	push: core_push,
	sort: [].sort,
	splice: [].splice
};

// Give the init function the jQuery prototype for later instantiation
// 把init函数给jQuery原型为稍后的实例化
jQuery.fn.init.prototype = jQuery.fn;

jQuery.extend = jQuery.fn.extend = function() {
	var src, copyIsArray, copy, name, options, clone,
		target = arguments[0] || {},
		i = 1,
		length = arguments.length,
		deep = false;

	// Handle a deep copy situation
	// 处理深度拷贝情况
	if ( typeof target === "boolean" ) {
		deep = target;
		target = arguments[1] || {};
		// skip the boolean and the target
		// 忽略布尔值和服务对象
		i = 2;
	}

	// Handle case when target is a string or something (possible in deep copy)
	// 处理事件当对象是一个字符串或其他东西
	if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
		target = {};
	}

	// extend jQuery itself if only one argument is passed
	// 如果只有一个参数是通过的,扩展jQuery本身
	if ( length === i ) {
		target = this;
		--i;
	}

	for ( ; i < length; i++ ) {
		// Only deal with non-null/undefined values
		// 只能处理 non-null/未定义 的值
		if ( (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 object
	// 返回被修改的对象
	return target;
};

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.
	// DOM文档是否准备被使用?一旦发生就设置为真。
	isReady: false,

	// A counter to track how many items to wait for before
	// 一个计数器跟踪多少项目等待
	// the ready event fires. See #6781
	// 准备好的事件。请看#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
	// 操纵DOM文档何时被准备
	ready: function( wait ) {

		// Abort if there are pending holds or we're already ready
		// 终止如果有待定的holds或者已经准备好了
		if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
			return;
		}

		// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
		// 确认body结构存在,至少,免得IE有点overzealous(暂时译为:过分热心)标签#5443
		if ( !document.body ) {
			return setTimeout( jQuery.ready );
		}

		// Remember that the DOM is ready
		// 记住文件对象模型(DOM)正在准备
		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").off("ready");
		}
	},

	// See test/unit/core.js for details concerning isFunction.
	// 看test/unit/core.js这个文件,为了详述concerning isFunction(暂时译为:关系到的函数)
	// Since version 1.3, DOM methods and functions like alert
	// 自从1.3版本,DOM方法和函数像警报
	// aren't supported. They return false on IE (#2968).
	// 不被支持。它们在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 ) {
		if ( obj == null ) {
			return String( obj );
		}
		return typeof obj === "object" || typeof obj === "function" ?
			class2type[ core_toString.call(obj) ] || "object" :
			typeof obj;
	},

	isPlainObject: function( obj ) {
		// Must be an Object.
		// 必须是对象
		// Because of IE, we also have to check the presence of the constructor property.
		// 由于IE的原因,我们必须检查存在的构造器属性
		// Make sure that DOM nodes and window objects don't pass through, as well
		// 还有确保DOM节点和window对象不被传进来
		if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
			return false;
		}

		try {
			// Not own constructor property must be Object
			// 拥有的构造器属性不一定是对象
			if ( obj.constructor &&
				!core_hasOwn.call(obj, "constructor") &&
				!core_hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
				return false;
			}
		} catch ( e ) {
			// IE8,9 Will throw exceptions on certain host objects #9897
			// IE8,9将会扔出例外在某些主机对象#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 || core_hasOwn.call( obj, key );
		//遍历对象中的变量key返回key没有找到
	},

	isEmptyObject: function( obj ) {
		var name;
		for ( name in obj ) {
			return false;
		}
		return true;
	},

	error: function( msg ) {
		throw new Error( msg );
	},

	// data: string of html
	// 数据:HTML的字符串
	// context (optional): If specified, the fragment will be created in this context, defaults to document
	// 上下文内容(任意的):如果被指定,片段会被创建到该上下文上,默认是创建在文档上
	// keepScripts (optional): If true, will include scripts passed in the html string
	// 保留脚本(可选的):如果为真,包含的脚本在html字符串中会通过
	parseHTML: function( data, context, keepScripts ) {// 解析HTML字符串,生成相应的dom元素并返回
		if ( !data || typeof data !== "string" ) {
			return null;
		}
		if ( typeof context === "boolean" ) {// 如果context是布尔类型,则将context的值赋给keepScripts,并将context设置为假
			keepScripts = context;
			context = false;
		}
		context = context || document;

		var parsed = rsingleTag.exec( data ),
			scripts = !keepScripts && [];

		// Single tag
		// 单独的标签
		if ( parsed ) {
			return [ context.createElement( parsed[1] ) ];
		}

		parsed = jQuery.buildFragment( [ data ], context, scripts );
		if ( scripts ) {
			jQuery( scripts ).remove();
		}
		return jQuery.merge( [], parsed.childNodes );
	},

	parseJSON: function( data ) {
		// Attempt to parse using the native JSON parser first
		// 首相尝试解析正在使用的本地的JSON解析程序
		if ( window.JSON && window.JSON.parse ) {
			return window.JSON.parse( data );
		}

		if ( data === null ) {
			return data;
		}

		if ( typeof data === "string" ) {

			// Make sure leading/trailing whitespace is removed (IE can't handle it)
			// 确认开头、末尾空白符号已被移走(IE无法操作)
			data = jQuery.trim( data );

			if ( data ) {
				// Make sure the incoming data is actual JSON
				// 确认输入的数据现在的JSON数据
				// Logic borrowed from http://json.org/json2.js
				// 从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解析
	parseXML: function( data ) {
		var xml, tmp;
		if ( !data || typeof data !== "string" ) {
			return null;//如果传入的数据类型不是字符串,返回空值。
		}
		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
	// 工作环境基于Jim Driscoll的发现
	// http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
	// 上面提到那人的一篇文章
CavanWang 2013-04-01
  • 打赏
  • 举报
回复
楼主精神可嘉啊,我也在看,目前是看源码,然后给他附加汉语的代码注释,理清框架和逻辑,希望大家加油啊
wohuifude123 2013-04-01
  • 打赏
  • 举报
回复
尾部翻译完了
// Create scrollLeft and scrollTop methods
// 创建滚动左面和滚动顶部方法
jQuery.each( {scrollLeft: "pageXOffset", scrollTop: "pageYOffset"}, function( method, prop ) {
	var top = /Y/.test( prop );

	jQuery.fn[ method ] = function( val ) {
		return jQuery.access( this, function( elem, method, val ) {
			var win = getWindow( elem );

			if ( val === undefined ) {
				return win ? (prop in win) ? win[ prop ] :
					win.document.documentElement[ method ] :
					elem[ method ];
			}

			if ( win ) {
				win.scrollTo(
					!top ? val : jQuery( win ).scrollLeft(),
					top ? val : jQuery( win ).scrollTop()
				);

			} else {
				elem[ method ] = val;
			}
		}, method, val, arguments.length, null );
	};
});

function getWindow( elem ) {
	return jQuery.isWindow( elem ) ?
		elem :
		elem.nodeType === 9 ?
			elem.defaultView || elem.parentWindow :
			false;
}
// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
// 创建内层高度、内层宽度、高度、宽度、整个窗口高度(outerHeight)和整个窗口的宽度(outerWidth)方法
jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
	jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) {
		// margin is only for outerHeight, outerWidth
		// 框架只是为了整个窗口高度和整个窗口的宽度
		jQuery.fn[ funcName ] = function( margin, value ) {
			var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
				extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );

			return jQuery.access( this, function( elem, type, value ) {
				var doc;

				if ( jQuery.isWindow( elem ) ) {
					// As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
					// 截至2012年5月8日对于移动Safari(苹果公司浏览器)产生不正确的结果,但是
					// isn't a whole lot we can do. See pull request at this URL for discussion:
					// 没有太多我们可做的。请求在这个URL地址进行讨论(See pull 感觉这里做动词不用翻译)
					// https://github.com/jquery/jquery/pull/764
					// 以上是网址
					return elem.document.documentElement[ "client" + name ];
				}

				// Get document width or height
				// 得到文档的宽度或者高度
				if ( elem.nodeType === 9 ) {
					doc = elem.documentElement;

					// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], whichever is greatest
					// 滚动(宽度或者高度)或者返回(宽度或者高度)或者客户端(宽度或者高度),无论哪个都是最大的
					// unfortunately, this causes bug #3838 in IE6/8 only, but there is currently no good, small way to fix it.
					// 不幸的是,这将导致错误#3838仅在IE6和IE8,但目前还没有很好的、精巧的方法解决它。
					return Math.max(
						elem.body[ "scroll" + name ], doc[ "scroll" + name ],
						elem.body[ "offset" + name ], doc[ "offset" + name ],
						doc[ "client" + name ]
					);
				}

				return value === undefined ?
					// Get width or height on the element, requesting but not forcing parseFloat
					// 得到宽度或高度的元素,要求但不强迫转换为浮点数
					jQuery.css( elem, type, extra ) :

					// Set width or height on the element
					// 设置宽度或高度的元素
					jQuery.style( elem, type, value, extra );
			}, type, chainable ? margin : undefined, chainable, null );
		};
	});
});
// Limit scope pollution from any deprecated API
// 从任何过时的API的限制范围污染(scope pollution暂时译为范围污染)
// (function(){})();
// 上句解释应该是对function(){}外又加了()进行解释,范围污染
// Expose jQuery to the global object
// 揭露jQuery作为全局对象
window.jQuery = window.$ = jQuery;

// Expose jQuery as an AMD module, but only for AMD loaders that
// 揭露jQuery为AMD的模块,但只有AMD的装载机
// understand the issues with loading multiple versions of jQuery
// 了解问题与加载多个版本的jQuery
// in a page that all might call define(). The loader will indicate
// 在一个网页有所有可能访问define()函数。加载程序将显示
// they have special allowances for multiple jQuery versions by
// 他们有特别的补助为多个版本的jQuery以(接下面)
// specifying define.amd.jQuery = true. Register as a named module,
// 指定定义。amd。jQuery为真。注册作为一个被命名的模板,
// since jQuery can be concatenated with other files that may use define,
// 由于jQuery可以被其他能使用的定义文件链接
// but not use a proper concatenation script that understands anonymous
// 而不是使用适当的链接脚本了解匿名
// AMD modules. A named AMD is safest and most robust way to register.
// ADM模板。一个命名AMD是最安全和最可靠的方法对于注册
// Lowercase jquery is used because AMD module names are derived from
// 小写jquery被使用因为AMD模块的名字是源于
// file names, and jQuery is normally delivered in a lowercase file name.
// 文件名字,并且jQuery通常源于小写文件名。
// Do this after creating the global so that if an AMD module wants to call
// 在创建全局后这么做以便一个AMD模板想要访问
// noConflict to hide this version of jQuery, it will work.
// 无冲突为了隐藏此版本的jQuery,它将会工作。
if ( typeof define === "function" && define.amd && define.amd.jQuery ) {
	define( "jquery", [], function () { return jQuery; } );
}

})( window );
/*
 * 1.传入window
 * 通过传入window变量,使得window由全局变量变为局部变量
 * 当在jQuery代码块中访问window时,不需要将作用域链回退到顶层作用域,这样可以更快的访问window
 * 更重要的是,将window作为参数传入,可以在压缩代码时进行优化
 * (function(a,b){})(window);window 被优化为 a,压缩后文件更小
 * 2.传入undefined
 * 是为了在“自调用匿名函数”的作用域内,确保undefined是真的未定义
 * 因为undefined能够被重写,赋予新的值 
 * undefined = "now it's defined";
 * alert( undefined );
 * 浏览器测试结果:
 * 浏览器测试结果结论
 * ienow it's defined可以改变
 * firefoxundefined不能改变
 * chromenow it's defined可以改变
 * operanow it's defined可以改变
 */
加载更多回复(21)
jquery中文汉化版 (function( window, undefined ) { //不要做这个因为各自的应用程序包括ASP.NET查找 // the stack via arguments.caller.callee and Firefox dies if //你尝试查找通过“精确使用”呼叫链接(#13335) //支持:火狐浏览器 18+ //“精确使用”; var //deferred对象被使用在DOM(Document Object Model翻译:文档对象模型)准备之时 //deferred(延迟)对象:从jQuery 1.5.0版本开始引入的一个新功能 //在DOM准备好时调用 readyList, //一个中心引用对于jQuery根文档 //对根jQuery对象的主要引用 rootjQuery, //支持:IE9之前的版本 // For `typeof node.method` instead of `node.method !== undefined` core_strundefined = typeof undefined, // Use the correct document accordingly with window argument (sandbox) document = window.document,//window文档赋值给变量document location = [removed], // Map over jQuery in case of overwrite(不确定,待修正,希望高人帮忙翻译一下) //在jQuery上绘制写在上面的实例 //防止被覆盖 _jQuery = window.jQuery, // Map over the $ in case of overwrite _$ = window.$, //将window正则表达式符号$赋值给变量_$ //[类]:成双类型 class2type = {}, //在贮存区被删除数据ID的列表,我们能够再用他们 core_deletedIds = [], core_version = "1.9.1", //保存一个参考给一些核心的方法 //为核心方法创建引用 core_concat = core_deletedIds.concat, core_push = core_deletedIds.push, core_slice = core_deletedIds.slice, core_indexOf = core_deletedIds.indexOf, core_toString = class2type.toString, core_hasOwn = class2type.hasOwnProperty, core_trim = core_version.trim, //规定一个jQuery本地代码 //构建jQuery对象 jQuery = function( selector, context ) { //jQuery对象是实际上初始化名为enhanced(提高的)构造器 //jQuery对象实际上只是增强的初始化构造方法 return new jQuery.fn.init( selector, context, rootjQuery ); }, /* 用来匹配数字的正则,匹配可选正负号、浮点型、整型、科学计数法 * 没有使用(?)来表示可选而是通过(|)来选择 * (?:\d*\.|)匹配浮点数时,|前的\d*\.可以匹配整数部分和小数点,小数部分由后面的\d+匹配 * 匹配整数时,|)可以保证匹配继续向下进行,整数由后面的\d+匹配,同样的\d+在匹配整型和浮点型时负责的匹配部分不同 * [eE][\-+]?\d+|)处理科学计数法的匹配,同样没有使用?表示可选 */ core_pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source, //用于分开空格 core_rnotwhite = /\S+/g, //查找非空白字符串 // Make sure we trim BOM and NBSP (here's looking at you, Safari 5.0 and IE) rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, //\uFEFF:字节顺序标志 //一个简单途径用于检查HTML字符串 // Prioritize #id over to avoid XSS via location.hash (#9521) // Strict HTML recognition (#11290: must start with <) rquickExpr = /^(?:(<[\w\W]+>)[^>]*|#([\w-]*))$/, //匹配一个独立的标签 rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/, // JSON RegExp(JavaScript Object Notation:JavaScript对象标记法正则表达式) rvalidchars = /^[\],:{}\s]*$/, rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, rvalidescape = /\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g, rvalidtokens = /"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g, // Matches dashed string for camelizing rmsPrefix = /^-ms-/, rdashAlpha = /-([\da-z])/gi, //以上为正则运算表达式各种形式,不太容易理解,尽量掌握
jquery中文汉化版 (function( window, undefined ) { //不要做这个因为各自的应用程序包括ASP.NET查找 // the stack via arguments.caller.callee and Firefox dies if //你尝试查找通过“精确使用”呼叫链接(#13335) //支持:火狐浏览器 18+ //“精确使用”; var //deferred对象被使用在DOM(Document Object Model翻译:文档对象模型)准备之时 //deferred(延迟)对象:从jQuery 1.5.0版本开始引入的一个新功能 //在DOM准备好时调用 readyList, //一个中心引用对于jQuery根文档 //对根jQuery对象的主要引用 rootjQuery, //支持:IE9之前的版本 // For `typeof node.method` instead of `node.method !== undefined` core_strundefined = typeof undefined, // Use the correct document accordingly with window argument (sandbox) document = window.document,//window文档赋值给变量document location = [removed], // Map over jQuery in case of overwrite(不确定,待修正,希望高人帮忙翻译一下) //在jQuery上绘制写在上面的实例 //防止被覆盖 _jQuery = window.jQuery, // Map over the $ in case of overwrite _$ = window.$, //将window正则表达式符号$赋值给变量_$ //[类]:成双类型 class2type = {}, //在贮存区被删除数据ID的列表,我们能够再用他们 core_deletedIds = [], core_version = "1.9.1", //保存一个参考给一些核心的方法 //为核心方法创建引用 core_concat = core_deletedIds.concat, core_push = core_deletedIds.push, core_slice = core_deletedIds.slice, core_indexOf = core_deletedIds.indexOf, core_toString = class2type.toString, core_hasOwn = class2type.hasOwnProperty, core_trim = core_version.trim, //规定一个jQuery本地代码 //构建jQuery对象 jQuery = function( selector, context ) { //jQuery对象是实际上初始化名为enhanced(提高的)构造器 //jQuery对象实际上只是增强的初始化构造方法 return new jQuery.fn.init( selector, context, rootjQuery ); }, /* 用来匹配数字的正则,匹配可选正负号、浮点型、整型、科学计数法 * 没有使用(?)来表示可选而是通过(|)来选择 * (?:\d*\.|)匹配浮点数时,|前的\d*\.可以匹配整数部分和小数点,小数部分由后面的\d+匹配 * 匹配整数时,|)可以保证匹配继续向下进行,整数由后面的\d+匹配,同样的\d+在匹配整型和浮点型时负责的匹配部分不同 * [eE][\-+]?\d+|)处理科学计数法的匹配,同样没有使用?表示可选 */ core_pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source, //用于分开空格 core_rnotwhite = /\S+/g, //查找非空白字符串 // Make sure we trim BOM and NBSP (here's looking at you, Safari 5.0 and IE) rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, //\uFEFF:字节顺序标志 //一个简单途径用于检查HTML字符串 // Prioritize #id over to avoid XSS via location.hash (#9521) // Strict HTML recognition (#11290: must start with <) rquickExpr = /^(?:(<[\w\W]+>)[^>]*|#([\w-]*))$/, //匹配一个独立的标签 rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/, // JSON RegExp(JavaScript Object Notation:JavaScript对象标记法正则表达式) rvalidchars = /^[\],:{}\s]*$/, rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, rvalidescape = /\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g, rvalidtokens = /"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g, // Matches dashed string for camelizing rmsPrefix = /^-ms-/, rdashAlpha = /-([\da-z])/gi, //以上为正则运算表达式各种形式,不太容易理解,尽量掌握。

87,914

社区成员

发帖
与我相关
我的任务
社区描述
Web 开发 JavaScript
社区管理员
  • JavaScript
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧