您的位置:首页 > Web前端 > JQuery

jQuery源码学习(1)——addClass

2012-12-20 14:18 337 查看
  最近比较闲,寻思着学习下jQuery源码,看了好多博客,很多都讲的比较详细。jQuery虽然只有那么200多K,但内容却比较丰富,对于我这样一个js菜鸟,看起来相当吃力。骨头太大,只能化整为零,从简单的小块开始。

    今天看了下class系列的方法,贴下来!可能网上已经有很多,就当做自己记录笔记吧,请勿喷饭!

//添加类
addClass: function( value ) {
var classNames, i, l, elem,
setClass, c, cl;

//如果value是一个函数,则调用这个函数得到运算结果,然后再递归调用addClass
if ( jQuery.isFunction( value ) ) {
return this.each(function( j ) {
jQuery( this ).addClass( value.call(this, j, this.className) );
});
}

if ( value && typeof value === "string" ) {
//得到传入的class数组
classNames = value.split( core_rspace );

//this表示调用此方法的jQuery对象,可能有多个
for ( i = 0, l = this.length; i < l; i++ ) {
elem = this[ i ];
//元素类型节点类型:元素element 1;属性attr 2;文本text 3;注释comments 8;文档document 9
//如果是元素节点
if ( elem.nodeType === 1 ) {
//如果元素没有class并且classNames数组只有一个元素,则直接赋值
if ( !elem.className && classNames.length === 1 ) {
elem.className = value;

} else {
setClass = " " + elem.className + " ";

//循环添加要加入的class
for ( c = 0, cl = classNames.length; c < cl; c++ ) {
if ( setClass.indexOf( " " + classNames[ c ] + " " ) < 0 ) {
setClass += classNames[ c ] + " ";
}
}
elem.className = jQuery.trim( setClass );
}
}
}
}
//返回获取的jQuery对象
return this;
},


//删除指定的类
removeClass: function( value ) {
var removes, className, elem, c, cl, i, l;

if ( jQuery.isFunction( value ) ) {
return this.each(function( j ) {
jQuery( this ).removeClass( value.call(this, j, this.className) );
});
}
if ( (value && typeof value === "string") || value === undefined ) {
removes = ( value || "" ).split( core_rspace );

for ( i = 0, l = this.length; i < l; i++ ) {
elem = this[ i ];
if ( elem.nodeType === 1 && elem.className ) {

//获取当前元素的class(用空格替换制表符或回车符、换行符)
className = (" " + elem.className + " ").replace( rclass, " " );

// loop over each item in the removal list
for ( c = 0, cl = removes.length; c < cl; c++ ) {
// Remove until there is nothing to remove,
while ( className.indexOf(" " + removes[ c ] + " ") >= 0 ) {
className = className.replace( " " + removes[ c ] + " " , " " );
}
}
//如果value为空,则直接去掉元素的所有class;否则使用处理后的className
elem.className = value ? jQuery.trim( className ) : "";
}
}
}
//大部分方法都是返回this,遍于进行链式操作
return this;
},


//如果没有class则添加,如果有则删除
//如果stateVal设置为true,则添加样式;如果为false,则删除样式
toggleClass: function( value, stateVal ) {
var type = typeof value,
//判断stateVal是否为boolean类型
isBool = typeof stateVal === "boolean";

//value为function时递归调用
if ( jQuery.isFunction( value ) ) {
return this.each(function( i ) {
jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );
});
}

return this.each(function() {
if ( type === "string" ) {
// toggle individual class names
var className,
i = 0,
self = jQuery( this ),
state = stateVal,
classNames = value.split( core_rspace );

//如果className[ i++ ] 存在
while ( (className = classNames[ i++ ]) ) {
// check each className given, space separated list
//如果第二个参数是boolean类型,则将第二个参数赋值给state;
//否则判断当前jQuery对象是否拥有className这个类,将判断结果取反,赋值给state
state = isBool ? state : !self.hasClass( className );
//如果state为true,则将className赋值给self['addClass'];
//如果state为false,则将className赋值为self['removeClass'],这里的self就是当前jQuery对象
self[ state ? "addClass" : "removeClass" ]( className );
}

} else if ( type === "undefined" || type === "boolean" ) {
if ( this.className ) {
// store className if set
jQuery._data( this, "__className__", this.className );
}

// toggle whole className
//如果className为空或者value为false,则直接清空对象的class;
//否则将保存的_className赋值给当前对象的className
this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || "";
}
});
},


//判断某个对象(或一个对象集中的第一个对象)是否拥有某个class
hasClass: function( selector ) {
var className = " " + selector + " ",
i = 0,
l = this.length;
for ( ; i < l; i++ ) {
if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) {
return true;
}
}

return false;
},
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: