87,910
社区成员
发帖
与我相关
我的任务
分享
/*!
* jQuery JavaScript Library v1.10.1
* http://jquery.com/
*
* Includes Sizzle.js
* http://sizzlejs.com/
*
* Copyright 2005, 2013 jQuery Foundation, Inc. and other contributors
* Released under the MIT license
* http://jquery.org/license
*
* Date: 2013-05-30T21:49Z
* 翻译日期: 2013年6月19日
* 翻译:刘建(毕业院校:家里蹲大学低能班)
* 联系邮箱:243376129@qq.com
* 原文地址:http://www.cnblogs.com/laonanren/archive/2013/02/14/2912145.html
* 翻译上的不足之处,希望大家能告诉我,我会尽量修改,本人才疏学浅,文化程度不高,希望大家多多包涵,我会努力改正。
*
* 与上个版本1.9.1的变化不大,所以我就接着我原来翻译的【jquery1.9.1中文汉化版】接着翻译了。
* 上个版本的发布日期为2013年2月4日,我很佩服他们的更新速度,太拼命了。
*
* 加入一些自己的学习javascript心得,还有这里涉及的某些东西的注释,不敢保证绝对正确,建议大家以参考为准。
* 有的汉化部分未能完全表达出原来英文的意思,所以留着英文原文,有能力还是看英文原文比较好,这个汉化只是个参考而已
* 关于jQuery2.0系列,因为更新的比较快,bug多点,所以暂时先不翻译,这个版本不支持IE6、7、8,估计普及还得需要一段时间
* 等更新慢下来,我再找个时间研究一下里面高深的内容,顺便翻译。
* 这些代码的注释很详细,所以翻译起来需要花些时间,反正我不会太监就是了。
* 有妹子想学javascript或者ps或者c++语言的,欢迎与我探讨,开个玩笑。
* 感谢那些曾经解答我学习js困惑的网上高手,最后,希望大家早日成为大神。
*/
//在实现delegate方法中,有一个很重要的辅助函数叫closest,现在它归类为遍历节点这个模块中。
closest: function( selectors, context ) {
var cur,
i = 0,
l = this.length,
ret = [],
pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
jQuery( selectors, context || this.context ) :
0;
// 如果字符串包含位置伪类或者是个元素节点,则封装为一个jQuery对象,否则为0(即false的简写,用于快速跳过分支)
for ( ; i < l; i++ ) {//遍历原jQuery对象的节点
for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) {
// Always skip document fragments
// 经常忽略文档碎片
if ( cur.nodeType < 11 && (pos ?
pos.index(cur) > -1 :
// Don't pass non-elements to Sizzle
// 不要把无元素传递给Sizzle
cur.nodeType === 1 &&
jQuery.find.matchesSelector(cur, selectors)) ) {
// 如果是jQuery对象,则判定其是否包含当前节点。
// 否则使用matchesSelector方法判定这个节点是否匹配给定的表达式selectors
cur = ret.push( cur );
// 是则放入选择器中
break;
}
}
}
return this.pushStack( ret.length > 1 ? jQuery.unique( ret ) : ret );
// 如果大于1,进行唯一化操作,否则将节点集合重新包装成一个新dom对象返回
},
// Determine the position of an element within
// the matched set of elements
// 在不超过匹配设置的元素范围内确定元素的位置
index: function( elem ) {
// No argument, return index in parent
// 没有参数,返回父级内的索引
if ( !elem ) {
return ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1;
}
// index in selector
// 选择器内的索引
if ( typeof elem === "string" ) {
return jQuery.inArray( this[0], jQuery( elem ) );
}
// Locate the position of the desired element
// 查找被请求元素的位置
return jQuery.inArray(
// If it receives a jQuery object, the first element is used
elem.jquery ? elem[0] : elem, this );
},
add: function( selector, context ) {
var set = typeof selector === "string" ?
jQuery( selector, context ) :
jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ),
all = jQuery.merge( this.get(), set );
return this.pushStack( jQuery.unique(all) );
},
addBack: function( selector ) {
return this.add( selector == null ?
this.prevObject : this.prevObject.filter(selector)
);
}
});
function sibling( cur, dir ) {
do {
cur = cur[ dir ];
} while ( cur && cur.nodeType !== 1 );
return cur;
}
jQuery.each({// 通过 each() 方法为 jQuery 对象映射一组引用 DOM 节点的方法
parent: function( elem ) { // 引用父节点
var parent = elem.parentNode;
return parent && parent.nodeType !== 11 ? parent : null;
},
parents: function( elem ) {
return jQuery.dir( elem, "parentNode" );// 引用所有父节点
},
parentsUntil: function( elem, i, until ) {
return jQuery.dir( elem, "parentNode", until );
},
next: function( elem ) {
return sibling( elem, "nextSibling" );
},
prev: function( elem ) {
return sibling( elem, "previousSibling" );
},
nextAll: function( elem ) {// 引用所有后继DOM元素
return jQuery.dir( elem, "nextSibling" );
},
prevAll: function( elem ) {// 引用所有前继DOM元素
return jQuery.dir( elem, "previousSibling" );
},
nextUntil: function( elem, i, until ) {
return jQuery.dir( elem, "nextSibling", until );
},
prevUntil: function( elem, i, until ) {
return jQuery.dir( elem, "previousSibling", until );
},
siblings: function( elem ) {// 引用相邻DOM元素
return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );
},
children: function( elem ) {// 引用所有子元素
return jQuery.sibling( elem.firstChild );
},
contents: function( elem ) {
return jQuery.nodeName( elem, "iframe" ) ?
elem.contentDocument || elem.contentWindow.document :
jQuery.merge( [], elem.childNodes );
// 如果存在iframe,就是文档,或者所有子节点
}
}, function( name, fn ) {// 为 jQuery 对象注册同名方法
jQuery.fn[ name ] = function( until, selector ) {
var ret = jQuery.map( this, fn, until );// 每个元素都执行同名方法
if ( name.slice( -5 ) !== "Until" ) {
selector = until;
}
if ( selector && typeof selector === "string" ) {
ret = jQuery.filter( selector, ret );// 过滤元素集
}
if ( this.length > 1 ) {
// Remove duplicates
// 移除派生物
if ( !guaranteedUnique[ name ] ) {
ret = jQuery.unique( ret );
}
// Reverse order for parents* and prev-derivatives
// 颠倒顺序关于父元素和前一个派生物
if ( rparentsprev.test( name ) ) {
ret = ret.reverse();
}
}
return this.pushStack( ret );// 返回构建的 jQuery 对象
};
});
jQuery.extend({
filter: function( expr, elems, not ) {
var elem = elems[ 0 ];
if ( not ) {
expr = ":not(" + expr + ")";
}
return elems.length === 1 && elem.nodeType === 1 ?
jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :
jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
return elem.nodeType === 1;
}));
},
// 从一个元素出发,检索某个方向上的所有元素
// 如可以把元素的 parentNode、nextSibling、previousSibling、lastChild、firstChild 属性作为方向
// 参数说明:
// elem 参数表示起点元素
// dir 参数表示元素的方向属性,如 parentNode、nextSibling、previousSibling、lastChild、
dir: function( elem, dir, until ) {
var matched = [],
cur = elem[ dir ];
while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
// 逐级迭代访问,直到访问到 document 节点
if ( cur.nodeType === 1 ) {// Element 类型
matched.push( cur );
}
cur = cur[dir];// 向上一级传递节点
}
return matched;
},
// 从包含参数 n 的元素开始检索所有后续相邻元素,但不包含参数 elem 指定的元素
// 参数说明:
// n 参数表示起点元素
// elem 参数排除元素
sibling: function( n, elem ) {
var r = [];
for ( ; n; n = n.nextSibling ) {
if ( n.nodeType === 1 && n !== elem ) {
r.push( n );
}
}
return r;
}
});
// Implement the identical functionality for filter and not
// 执行相同的功能性关于滤镜和不是滤镜
var string = "新建文件\\/夹"
var reg = /[\\\/:*?"<>|]+/g;
document.write(string);
document.write("<br />");
document.write(string.match(reg));
会匹配出\/
事例②
var string = "新建文件\\/夹"
var reg = new RegExp('[\\\\/:*?\\"<>|]+');
document.write(string);
document.write("<br />");
document.write(string.match(reg));
显示出同样的结果
如果使用RegExp()需要进行双转义,这就是①与②结果相同但写法却明显不同的原因
双转义事例
var string = "新\"建/文\\\\件夹";
var reg = new RegExp('\\\\\\\\');
document.write(string);
document.write("<br />");
document.write(string.match(reg));
document.write("<br />");
function MatchDemo()
{
var r, re; // 声明变量。
var s = "The rain in Spain falls mainly in the plain";
re = /ain/i; // 创建正则表达式模式。
r = s.match(re); // 尝试匹配搜索字符串。
return(r); // 返回第一次出现 "ain" 的地方。
}
document.write(MatchDemo());
如果匹配一个/符号,需要进行两次转义
var reg = new RegExp('\\\\');
红色的部分可以看成是【新建文件\\夹】第一个\含义
蓝色的部分可以看成是正则表达式中的转义符号// 从 复选框/单选按钮 接受本地改变事件,我们已经在上面触发他们了
if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) {
return event.handleObj.handler.apply( this, arguments );
}
},
teardown: function() {
jQuery.event.remove( this, "._change" );
return !rformElems.test( this.nodeName );
}
};
}
// Create "bubbling" focus and blur events
// 创建bubbling聚焦和模糊事件
if ( !jQuery.support.focusinBubbles ) {
// focusin/ focusout 可冒泡事件实现原理是,在事件捕获阶段监视特定元素的 focus/ blur 动作,
// 捕获行为发生在 document 对象上,这样才能有效地实现所有元素都能可以冒泡的事件。
// 一旦程序监视到存在 focus/ blur 行为,就会触发绑定在 document 元素上的事件处理程序,
// 该事件处理程序在内部调用 simulate 逻辑触发事件冒泡,以实现我们希望的可冒泡事件。
// 源码如下:
jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
// Attach a single capturing handler while someone wants focusin/focusout
// 附加一个独自的捕捉处理器某人想要focusin/focusout
var attaches = 0,
handler = function( event ) {
jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );
};
jQuery.event.special[ fix ] = {
setup: function() {
if ( attaches++ === 0 ) {
document.addEventListener( orig, handler, true );
// 在 focus/blur 事件的捕获阶段添加事件监听,直接在 document 上监视,同时防止过多绑定
}
},
teardown: function() {
if ( --attaches === 0 ) {
document.removeEventListener( orig, handler, true );
}
}
};
});
}
jQuery.fn.extend({// 注册事件处理器
on: function( types, selector, data, fn, /*INTERNAL*/ one ) {
var type, origFn;
// Types can be a map of types/handlers
// Types 能够是 types/handlers 的一张图
if ( typeof types === "object" ) {
// ( types-Object, selector, data )
if ( typeof selector !== "string" ) {
// ( types-Object, data )
data = data || selector;
selector = undefined;
}
for ( type in types ) {
this.on( type, selector, data, types[ type ], one );
}
return this;
}
if ( data == null && fn == null ) {// 以下是根据某些参数有无,对data和selector采取一定的判定匹配措施
// ( types, fn )
fn = selector;
data = selector = undefined;
} else if ( fn == null ) {
if ( typeof selector === "string" ) {
// ( types, selector, fn )
fn = data;
data = undefined;
} else {
// ( types, data, fn )
fn = data;
data = selector;
selector = undefined;
}
}
if ( fn === false ) {// 当fn赋值为false时,用返回值为false的函数替换,相当于是一个快捷键
fn = returnFalse;
} else if ( !fn ) {
return this;
}
if ( one === 1 ) {// one参数是内部调用的,one为1表示事件只在内部被调用一次
origFn = fn;
fn = function( event ) {
// Can use an empty set, since event contains the info
// 创建jQuery空对象,调用off方法,传入带有信息的event参数(其中包括注册时的所有信息),在off中
// 会对event对象做特殊处理,从而删除指定type的handler,保证只调用一次
jQuery().off( event );
return origFn.apply( this, arguments );
};
// Use same guid so caller can remove using origFn
// 使用相同的guid以便访问者能够移除使用origFn
// guid 解释:全局唯一标识符(Globally Unique Identifier)不知道这里指的是不是这个意思,待定。
// origFn解释:一个变量
fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
}
return this.each( function() {
jQuery.event.add( this, types, fn, data, selector );
});
},
one: function( types, selector, data, fn ) {// 注册只能被触发一次的事件处理器
return this.on( types, selector, data, fn, 1 );
},
off: function( types, selector, fn ) {
var handleObj, type;
if ( types && types.preventDefault && types.handleObj ) {
// 如果传进来的是event对象,那么进行如下处理(因为event对象包含off事件处理器需要的全部信息)
// ( event ) dispatched jQuery.Event
handleObj = types.handleObj;
jQuery( types.delegateTarget ).off(
handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType,
handleObj.selector,
handleObj.handler
);
return this;
}
if ( typeof types === "object" ) { //如果types的类型不是对象
// types可以为对象,是类型/函数对集合,同上面的on
// ( types-object [, selector] )
// types-object应该指的是上面那个( typeof types === "object" )
// selector指的应该是this.off( type, selector, types[ type ] )这里的selector
// selector翻译:选择器
for ( type in types ) {
this.off( type, selector, types[ type ] );
}
return this;
}
if ( selector === false || typeof selector === "function" ) {// 只有两个参数的情况
// ( types [, fn] )
// 上面这句翻译不成句子,应该是对上面代码的扩展内容
// types指的是上面那个
// fn是下面的
fn = selector;
selector = undefined;
}
if ( fn === false ) {// 当fn赋值为false时,用返回值为false的函数替换,相当于是一个快捷键
fn = returnFalse;
}
return this.each(function() {
jQuery.event.remove( this, types, fn, selector );
});
},
trigger: function( type, data ) {// 触发指定类型的事件回调函数列表
return this.each(function() {
jQuery.event.trigger( type, data, this );
});
},
triggerHandler: function( type, data ) {
// 与trigger几乎相同,不同的是,它只对jQuery集合中的第一个元素trigger,而且不冒泡,不执行默认操作
// 其内部调用trigger,用最后一个参数来区别
var elem = this[0];
if ( elem ) {
return jQuery.event.trigger( type, data, elem, true );
}
}
});
var isSimple = /^.[^:#\[\.,]*$/,
rparentsprev = /^(?:parents|prev(?:Until|All))/,
rneedsContext = jQuery.expr.match.needsContext,
// methods guaranteed to produce a unique set when starting from a unique set
// 方法保证产生唯一的设置当从唯一的设置开始
guaranteedUnique = {
children: true,
contents: true,
next: true,
prev: true
};
jQuery.fn.extend({
find: function( selector ) {
var i,
ret = [],
self = this,
len = self.length;
if ( typeof selector !== "string" ) {
return this.pushStack( jQuery( selector ).filter(function() {
for ( i = 0; i < len; i++ ) {
if ( jQuery.contains( self[ i ], this ) ) {
return true;
}
}
}) );
}
for ( i = 0; i < len; i++ ) {
jQuery.find( selector, self[ i ], ret );
}
// Needed because $( selector, context ) becomes $( context ).find( selector )
// 被需要因为$( selector, context )变成了$( context ).find( selector )
// 这里我理解为将原来的一种写法变成了一种新的写法,不知道对不对。
ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );
ret.selector = this.selector ? this.selector + " " + selector : selector;
return ret;
},
has: function( target ) {
var i,
targets = jQuery( target, this ),
len = targets.length;
return this.filter(function() {
for ( i = 0; i < len; i++ ) {
if ( jQuery.contains( this, targets[i] ) ) {
return true;
}
}
});
},
not: function( selector ) {
return this.pushStack( winnow(this, selector || [], true) );
},
filter: function( selector ) {
return this.pushStack( winnow(this, selector || [], false) );
},
is: function( selector ) {
return !!winnow(
this,
// If this is a positional/relative selector, check membership in the returned set
// 如果这是一个 按位/相对 选择器,在返回的设置内核实成员身份
// so $("p:first").is("p:last") won't return true for a doc with two "p".
// 所以$("p:first").is("p:last")不会返回真关于带有两个"p"的doc
typeof selector === "string" && rneedsContext.test( selector ) ?
jQuery( selector ) :
selector || [],
false
).length;
},
//在实现delegate方法中,有一个很重要的辅助函数叫closest,现在它归类为遍历节点这个模块中。
Ajax.Request(
url,
{
method:method,
parameters:para,
postBody:xmlString,
asynchronous:true,
setRequestHeader:Object,
onComplete:completeFun,
onError:errorFun
}
)
发送异步请求。(此方法是为兼容 prototype.js 而写,调用风格与 prototype 一致,使用Ajax.Request此方法请在页面中加载此js文件)
参数
url
必选项。数据发送的目标地址。
method
可选项。数据提交的方式,默认值为get。常用的还有post。
parameters
当 method 为 get 时是可选项,为 post 时是必选项。发送的数据,其形式为: name1=valeu1& name2=value2&name3=value3......
postBody
可选项。客户端发送的 xml 格式字符串。如果启用 postBody,那么 parameters 将被忽略。
asynchronous
可选项。指定请求是否异步,默认为true(异步)。
setRequestHeader
指定请求的头部字串。其值类型为“名称值对”形式的对象,比如:{"If-Modified-Since":"0", "SOAPAction":"http://tempuri.org/SBS_WebService", ... ... }
onComplete
可选项。请求成功时执行的回调函数,该函数默认把当前使用 xmlhttp 对象作为第一个参数。
onError
可选项。请求异常时执行的回调函数,该函数默认把当前使用 xmlhttp 对象作为第一个参数。
返回值
当前使用的 xmlhttp 对象。
描述
发送异步请求,并返回 xmlhttp 对象,该对象内置有 abort() 方法,用于提前终止请求。异步请求成功则执行 onComplete,失败则执行 onError 。并返回 xmlhttp 对象。
Ajax.Request 是个接口完整的 Ajax 方法,是 myJSFrame 中所有其他 Ajax 方法的核心方法。
用AJAX 发送到后台
proytype方法:
function changeshow()
{
var bid=document.fenlei.bfenlei.value;
var url = 'adm_mod_ajax.php';
var pars = 'mtype=1&mid=' + mid+'&bid='+bid;
var myAjax = new Ajax.Request(
url,
{
method: 'post',
parameters: pars,
onComplete: showResponse
}
);
}
// 这里我理解为将原来的一种写法变成了一种新的写法,不知道对不对。
ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );
ret.selector = this.selector ? this.selector + " " + selector : selector;
return ret;
},
has: function( target ) {
var i,
targets = jQuery( target, this ),
len = targets.length;
return this.filter(function() {
for ( i = 0; i < len; i++ ) {
if ( jQuery.contains( this, targets[i] ) ) {
return true;
}
}
});
},
not: function( selector ) {
return this.pushStack( winnow(this, selector || [], true) );
},
filter: function( selector ) {
return this.pushStack( winnow(this, selector || [], false) );
},
is: function( selector ) {
return !!winnow(
this,
// If this is a positional/relative selector, check membership in the returned set
// 如果这是一个 按位/相对 选择器,在返回的设置内核实成员身份
// so $("p:first").is("p:last") won't return true for a doc with two "p".
// 所以$("p:first").is("p:last")不会返回真关于带有两个"p"的doc
typeof selector === "string" && rneedsContext.test( selector ) ?
jQuery( selector ) :
selector || [],
false
).length;
},
//在实现delegate方法中,有一个很重要的辅助函数叫closest,现在它归类为遍历节点这个模块中。
closest: function( selectors, context ) {
var cur,
i = 0,
l = this.length,
ret = [],
pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
jQuery( selectors, context || this.context ) :
0;
// 如果字符串包含位置伪类或者是个元素节点,则封装为一个jQuery对象,否则为0(即false的简写,用于快速跳过分支)
for ( ; i < l; i++ ) {//遍历原jQuery对象的节点
for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) {
// Always skip document fragments
// 经常忽略文档碎片
if ( cur.nodeType < 11 && (pos ?
pos.index(cur) > -1 :
// Don't pass non-elements to Sizzle
// 不要把无元素传递给Sizzle
cur.nodeType === 1 &&
jQuery.find.matchesSelector(cur, selectors)) ) {
// 如果是jQuery对象,则判定其是否包含当前节点。
// 否则使用matchesSelector方法判定这个节点是否匹配给定的表达式selectors
cur = ret.push( cur );
// 是则放入选择器中
break;
}
}
}
return this.pushStack( ret.length > 1 ? jQuery.unique( ret ) : ret );
// 如果大于1,进行唯一化操作,否则将节点集合重新包装成一个新dom对象返回
},
// Determine the position of an element within
// the matched set of elements
// 在不超过匹配设置的元素范围内确定元素的位置
index: function( elem ) {
// No argument, return index in parent
// 没有参数,返回父级内的索引
if ( !elem ) {
return ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1;
}
// index in selector
// 选择器内的索引
if ( typeof elem === "string" ) {
return jQuery.inArray( this[0], jQuery( elem ) );
}
// Locate the position of the desired element
// 查找被请求元素的位置
return jQuery.inArray(
// If it receives a jQuery object, the first element is used
elem.jquery ? elem[0] : elem, this );
},
add: function( selector, context ) {
var set = typeof selector === "string" ?
jQuery( selector, context ) :
jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ),
all = jQuery.merge( this.get(), set );
return this.pushStack( jQuery.unique(all) );
},
addBack: function( selector ) {
return this.add( selector == null ?
this.prevObject : this.prevObject.filter(selector)
);
}
});
function sibling( cur, dir ) {
do {
cur = cur[ dir ];
} while ( cur && cur.nodeType !== 1 );
return cur;
}
jQuery.each({// 通过 each() 方法为 jQuery 对象映射一组引用 DOM 节点的方法
parent: function( elem ) { // 引用父节点
var parent = elem.parentNode;
return parent && parent.nodeType !== 11 ? parent : null;
},
parents: function( elem ) {
return jQuery.dir( elem, "parentNode" );// 引用所有父节点
},
parentsUntil: function( elem, i, until ) {
return jQuery.dir( elem, "parentNode", until );
},
next: function( elem ) {
return sibling( elem, "nextSibling" );
},
prev: function( elem ) {
return sibling( elem, "previousSibling" );
},
nextAll: function( elem ) {// 引用所有后继DOM元素
return jQuery.dir( elem, "nextSibling" );
},
prevAll: function( elem ) {// 引用所有前继DOM元素
return jQuery.dir( elem, "previousSibling" );
},
nextUntil: function( elem, i, until ) {
return jQuery.dir( elem, "nextSibling", until );
},
prevUntil: function( elem, i, until ) {
return jQuery.dir( elem, "previousSibling", until );
},
siblings: function( elem ) {// 引用相邻DOM元素
return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );
},
children: function( elem ) {// 引用所有子元素
return jQuery.sibling( elem.firstChild );
},
contents: function( elem ) {
return jQuery.nodeName( elem, "iframe" ) ?
elem.contentDocument || elem.contentWindow.document :
jQuery.merge( [], elem.childNodes );
// 如果存在iframe,就是文档,或者所有子节点
}
}, function( name, fn ) {// 为 jQuery 对象注册同名方法
jQuery.fn[ name ] = function( until, selector ) {
var ret = jQuery.map( this, fn, until );// 每个元素都执行同名方法
if ( name.slice( -5 ) !== "Until" ) {
selector = until;
}
if ( selector && typeof selector === "string" ) {
ret = jQuery.filter( selector, ret );// 过滤元素集
}
if ( this.length > 1 ) {
// Remove duplicates
// 移除派生物
if ( !guaranteedUnique[ name ] ) {
ret = jQuery.unique( ret );
}
// Reverse order for parents* and prev-derivatives
// 颠倒顺序关于父元素和前一个派生物
if ( rparentsprev.test( name ) ) {
ret = ret.reverse();
}
}
return this.pushStack( ret );// 返回构建的 jQuery 对象
};
});
jQuery.extend({
filter: function( expr, elems, not ) {
var elem = elems[ 0 ];
if ( not ) {
expr = ":not(" + expr + ")";
}
return elems.length === 1 && elem.nodeType === 1 ?
jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :
jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
return elem.nodeType === 1;
}));
},
// 从一个元素出发,检索某个方向上的所有元素
// 如可以把元素的 parentNode、nextSibling、previousSibling、lastChild、firstChild 属性作为方向
// 参数说明:
// elem 参数表示起点元素
// dir 参数表示元素的方向属性,如 parentNode、nextSibling、previousSibling、lastChild、
var r= /^(\d{4})-(\d{1,2})-(\d{1,2})$/; //正则表达式 匹配出生日期(简单匹配)
r.exec('1985-10-15');//exec() 方法用于检索字符串中的正则表达式的匹配。
s1=RegExp.$1;s2=RegExp.$2;s3=RegExp.$3;alert(s1+" "+s2+" "+s3)//结果为1985 10 15
正好今天看到一个回复里面的答案符合上面,一起写出来
<script>
var str=",42:5.000,142:8.00,";
var a = "42", n = "12.00";
document.write(str);
document.write("<br />");
str=str.replace(new RegExp("((^|,)"+a+":)[^,]+"),"$1"+n);//这个正则表达式是重点
document.write(str);
// ((^|,)"+a+":)代表$1
// (^|,)这句代表【^】或者【,】其实也可以直接变为(,"+a+":)
// 下面这句"+a+"也很重要。加了双引号使得【a】变成了变量
</script>
// 从 复选框/单选按钮 接受本地改变事件,我们已经在上面触发他们了
if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) {
return event.handleObj.handler.apply( this, arguments );
}
},
teardown: function() {
jQuery.event.remove( this, "._change" );
return !rformElems.test( this.nodeName );
}
};
}
// Create "bubbling" focus and blur events
// 创建bubbling聚焦和模糊事件
if ( !jQuery.support.focusinBubbles ) {
// focusin/ focusout 可冒泡事件实现原理是,在事件捕获阶段监视特定元素的 focus/ blur 动作,
// 捕获行为发生在 document 对象上,这样才能有效地实现所有元素都能可以冒泡的事件。
// 一旦程序监视到存在 focus/ blur 行为,就会触发绑定在 document 元素上的事件处理程序,
// 该事件处理程序在内部调用 simulate 逻辑触发事件冒泡,以实现我们希望的可冒泡事件。
// 源码如下:
jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
// Attach a single capturing handler while someone wants focusin/focusout
// 附加一个独自的捕捉处理器某人想要focusin/focusout
var attaches = 0,
handler = function( event ) {
jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );
};
jQuery.event.special[ fix ] = {
setup: function() {
if ( attaches++ === 0 ) {
document.addEventListener( orig, handler, true );
// 在 focus/blur 事件的捕获阶段添加事件监听,直接在 document 上监视,同时防止过多绑定
}
},
teardown: function() {
if ( --attaches === 0 ) {
document.removeEventListener( orig, handler, true );
}
}
};
});
}
jQuery.fn.extend({// 注册事件处理器
on: function( types, selector, data, fn, /*INTERNAL*/ one ) {
var type, origFn;
// Types can be a map of types/handlers
// Types 能够是 types/handlers 的一张图
if ( typeof types === "object" ) {
// ( types-Object, selector, data )
if ( typeof selector !== "string" ) {
// ( types-Object, data )
data = data || selector;
selector = undefined;
}
for ( type in types ) {
this.on( type, selector, data, types[ type ], one );
}
return this;
}
if ( data == null && fn == null ) {// 以下是根据某些参数有无,对data和selector采取一定的判定匹配措施
// ( types, fn )
fn = selector;
data = selector = undefined;
} else if ( fn == null ) {
if ( typeof selector === "string" ) {
// ( types, selector, fn )
fn = data;
data = undefined;
} else {
// ( types, data, fn )
fn = data;
data = selector;
selector = undefined;
}
}
if ( fn === false ) {// 当fn赋值为false时,用返回值为false的函数替换,相当于是一个快捷键
fn = returnFalse;
} else if ( !fn ) {
return this;
}
if ( one === 1 ) {// one参数是内部调用的,one为1表示事件只在内部被调用一次
origFn = fn;
fn = function( event ) {
// Can use an empty set, since event contains the info
// 创建jQuery空对象,调用off方法,传入带有信息的event参数(其中包括注册时的所有信息),在off中
// 会对event对象做特殊处理,从而删除指定type的handler,保证只调用一次
jQuery().off( event );
return origFn.apply( this, arguments );
};
// Use same guid so caller can remove using origFn
// 使用相同的guid以便访问者能够移除使用origFn
// guid 解释:全局唯一标识符(Globally Unique Identifier)不知道这里指的是不是这个意思,待定。
// origFn解释:一个变量
fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
}
return this.each( function() {
jQuery.event.add( this, types, fn, data, selector );
});
},
one: function( types, selector, data, fn ) {// 注册只能被触发一次的事件处理器
return this.on( types, selector, data, fn, 1 );
},
off: function( types, selector, fn ) {
var handleObj, type;
if ( types && types.preventDefault && types.handleObj ) {
// 如果传进来的是event对象,那么进行如下处理(因为event对象包含off事件处理器需要的全部信息)
// ( event ) dispatched jQuery.Event
handleObj = types.handleObj;
jQuery( types.delegateTarget ).off(
handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType,
handleObj.selector,
handleObj.handler
);
return this;
}
if ( typeof types === "object" ) { //如果types的类型不是对象
// types可以为对象,是类型/函数对集合,同上面的on
// ( types-object [, selector] )
// types-object应该指的是上面那个( typeof types === "object" )
// selector指的应该是this.off( type, selector, types[ type ] )这里的selector
// selector翻译:选择器
for ( type in types ) {
this.off( type, selector, types[ type ] );
}
return this;
}
if ( selector === false || typeof selector === "function" ) {// 只有两个参数的情况
// ( types [, fn] )
// 上面这句翻译不成句子,应该是对上面代码的扩展内容
// types指的是上面那个
// fn是下面的
fn = selector;
selector = undefined;
}
if ( fn === false ) {// 当fn赋值为false时,用返回值为false的函数替换,相当于是一个快捷键
fn = returnFalse;
}
return this.each(function() {
jQuery.event.remove( this, types, fn, selector );
});
},
trigger: function( type, data ) {// 触发指定类型的事件回调函数列表
return this.each(function() {
jQuery.event.trigger( type, data, this );
});
},
triggerHandler: function( type, data ) {
// 与trigger几乎相同,不同的是,它只对jQuery集合中的第一个元素trigger,而且不冒泡,不执行默认操作
// 其内部调用trigger,用最后一个参数来区别
var elem = this[0];
if ( elem ) {
return jQuery.event.trigger( type, data, elem, true );
}
}
});
var isSimple = /^.[^:#\[\.,]*$/,
rparentsprev = /^(?:parents|prev(?:Until|All))/,
rneedsContext = jQuery.expr.match.needsContext,
// methods guaranteed to produce a unique set when starting from a unique set
// 方法保证产生唯一的设置当从唯一的设置开始
guaranteedUnique = {
children: true,
contents: true,
next: true,
prev: true
};
jQuery.fn.extend({
find: function( selector ) {
var i,
ret = [],
self = this,
len = self.length;
if ( typeof selector !== "string" ) {
return this.pushStack( jQuery( selector ).filter(function() {
for ( i = 0; i < len; i++ ) {
if ( jQuery.contains( self[ i ], this ) ) {
return true;
}
}
}) );
}
for ( i = 0; i < len; i++ ) {
jQuery.find( selector, self[ i ], ret );
}
// Needed because $( selector, context ) becomes $( context ).find( selector )
// 被需要因为$( selector, context )变成了$( context ).find( selector )
// 这里我理解为将原来的一种写法变成了一种新的写法,不知道对不对。
// IE 提交代理
if ( !jQuery.support.submitBubbles ) {
jQuery.event.special.submit = {
setup: function() {
// Only need this for delegated form submit events
// 关于代理表单提交事件只需要这个
if ( jQuery.nodeName( this, "form" ) ) {
return false;
}
// Lazy-add a submit handler when a descendant form may potentially be submitted
// 懒惰添加 提交处理器 当派生表单可能被提交
jQuery.event.add( this, "click._submit keypress._submit", function( e ) {
// Node name check avoids a VML-related crash in IE (#9807)
// 节点名字检索阻止IE内的VML-related崩溃
var elem = e.target,
form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined;
if ( form && !jQuery._data( form, "submitBubbles" ) ) {
jQuery.event.add( form, "submit._submit", function( event ) {
event._submit_bubble = true;
});
jQuery._data( form, "submitBubbles", true );
}
});
// return undefined since we don't need an event listener
// 由于我们不需要事件监听,所以返回未定义
},
postDispatch: function( event ) {
// If form was submitted by the user, bubble the event up the tree
// 如果使用者提交了表单,让事件冒泡上升到树结构中
if ( event._submit_bubble ) {
delete event._submit_bubble;
if ( this.parentNode && !event.isTrigger ) {
jQuery.event.simulate( "submit", this.parentNode, event, true );
}
}
},
teardown: function() {
// Only need this for delegated form submit events
// 关于代理表单提交事件仅仅需要这个
if ( jQuery.nodeName( this, "form" ) ) {
return false;
}
// Remove delegated handlers; cleanData eventually reaps submit handlers attached above
// 移除代理处理器; cleanData最后获得被加在上面的提交处理器
jQuery.event.remove( this, "._submit" );
}
};
}
// IE change delegation and checkbox/radio fix
// IE 改变代理和 checkbox/radio 修正
if ( !jQuery.support.changeBubbles ) {
jQuery.event.special.change = {
setup: function() {
if ( rformElems.test( this.nodeName ) ) {
// IE doesn't fire change on a check/radio until blur; trigger it on click
// IE 不会放弃改变在一个 复选框/单选按钮 直到模糊; 点击触发他在属性改变后
// after a propertychange. Eat the blur-change in special.change.handle.
// 在特殊变化处理器内消化模糊改变
// This still fires onchange a second time for check/radio after blur.
// 在模糊后这仍然再次放弃onchange事件关于 复选框/单选按钮
if ( this.type === "checkbox" || this.type === "radio" ) {
jQuery.event.add( this, "propertychange._change", function( event ) {
if ( event.originalEvent.propertyName === "checked" ) {
this._just_changed = true;
}
});
jQuery.event.add( this, "click._change", function( event ) {
if ( this._just_changed && !event.isTrigger ) {
this._just_changed = false;
}
// Allow triggered, simulated change events (#11500)
// 允许被触发的,模拟的改变事件(#11500)
jQuery.event.simulate( "change", this, event, true );
});
}
return false;
}
// Delegated event; lazy-add a change handler on descendant inputs
// 委托事件:懒惰添加一个改变的处理器在派生的输出(这个翻译估计不准,这句话不太会翻译,见谅)
// 什么是委托事件?比如你按一个按钮去实现某种功能,点击按钮后传输信息区实现这个功能的过程就是委托。
jQuery.event.add( this, "beforeactivate._change", function( e ) {
var elem = e.target;
if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "changeBubbles" ) ) {
jQuery.event.add( elem, "change._change", function( event ) {
if ( this.parentNode && !event.isSimulated && !event.isTrigger ) {
jQuery.event.simulate( "change", this.parentNode, event, true );
}
});
jQuery._data( elem, "changeBubbles", true );
}
});
},
handle: function( event ) {
var elem = event.target;
// Swallow native change events from checkbox/radio, we already triggered them above
// 从 复选框/单选按钮 接受本地改变事件,我们已经在上面触发他们了