对于一般人来说,只要可以使用jQuery已经封装好的函数来达到目的即可。但是对于一名想要不断突破的你来说,是需要一番功夫去探究其内部是如何运行的,如此才能在前行的路上无论遇到什么困难都可以解决。
话不多说,让我们开始细看addClass()函数在jQuery内部是如何的进行的吧。
对jQuery有一定了解的人必定知道addClass()函数的便利,它可以只用简简单单的一行代码从而对某个标签添加一个类名从而实现一些动态变换,它往往和removeClass()配合使用。
<div class="clearfix nav">
<a class="logo" href="javascript:;"></a>
<ul class="clearfix nav-wrap">
<li><a class="nav-item nav-active" href="index.html">首页</a></li>
<li><a class="nav-item" href="pinpai.html">品牌故事</a></li>
<li><a class="nav-item" href="meishi.html">美食系列</a></li>
<li><a class="nav-item" href="shop.html">店面展示</a></li>
<li><a class="nav-item" href="news.html">新闻资讯</a></li>
<li><a class="nav-item" href="about-us.html">关于我们</a></li>
</ul>
</div>
.nav-wrap>li,.nav-item{
float: left; /*li标签横排显示*/
line-height: 88px;
width: 138px;
text-align: center;
color: #533336;
font-size: 18px;
}
.nav-item:hover{
background-color: #533336; /*背景颜色*/
color: #fff; /*字体颜色*/
}
.nav-wrap .nav-active{
background-color: #533336;
color: #FFFFFF;
}
$(".nav-item").click(function(){
$(this).parent("li").siblings().children().removeClass("nav-active");
//点击对象的父级(li)的兄弟级(li)的子集(a)移除类
$(this).addClass("nav-active");
//给点击对象添加类
});
根据代码可知,该功能是当点击导航里某一项时,当前项会removeClass("nav-active"); 被点击项会addClass("nav-active");
那么addClass()函数在jQuery内部又是如何运作的呢?
jQuery = function( selector, context ) {//selector = a.nav-item context = undefined
return new jQuery.fn.init( selector, context );}
// Need init if jQuery is called (just allow error to be thrown if not included)
//jQuery->$
//jQuery.fn.extend(object);给jQuery对象添加方法
//jQuery.extend(object); 为扩展jQuery类本身.为类添加新的方法
jQuery.fn.extend({
addClass: function( value ) {//传入value值 value="nav-active"
var classes, elem, cur, clazz, j, finalValue,
i = 0,
len = this.length, //len=1;
proceed = typeof value === "string" && value;//proceed = "nav-active" value = "nav-active" typeof value="string"
//typeof是最好的用来查看某个原始值的类型的方式.
//===是要求俩边不管值还是类型都要一致, 而== 则不会要求类型也必须一致
//typeof value === "string" && value; 相等 返回true 不等返回false
if ( jQuery.isFunction( value ) ) {
return this.each(function( j ) {
jQuery( this ).addClass( value.call( this, j, this.className ) );
}); //用value来替换this
}
isFunction: function( obj ) {
return jQuery.type(obj) === "function";//jQuery.type(obj)="string" obj="nav-active"
}
type: function( obj ) {//判断obj的type函数
if ( obj == null ) {
return obj + "";
}
return typeof obj === "object" || typeof obj === "function" ?//typeof obj="string"
class2type[ toString.call(obj) ] || "object" ://不懂
typeof obj;
},
/*console.log("5:" + typeof e);
var f = {};
object
var e = function() {};
console.log("5:" + typeof e);
function
var l = /^[-+]?\d+$/;
console.log("12:" + typeof l);
object
typeof null 为'object'
使用两等号, null == undefined 为真.*/
if ( proceed ) { //proceed = "nav-active"
classes = ( value || "" ).match( rnotwhite ) || [];//classes = ["nav-active"], value = "nav-active"
//classes = ( value || "" ).match( rnotwhite ) || [];不懂
for ( ; i < len; i++ ) { //i = 0, len = 1
elem = this[ i ]; //elem = a.nav-item 不懂this[ i ]
cur = elem.nodeType === 1 && ( elem.className ?//elem.className=="nav-item"
( " " + elem.className + " " ).replace( rclass, " " ) ://不懂 rclass
" "
);
//nodeType 属性返回以数字值返回指定节点的节点类型。
//如果节点是元素节点,则 nodeType 属性将返回 1。
//如果节点是属性节点,则 nodeType 属性将返回 2。
if ( cur ) { //cur = " nav-item "
j = 0;
while ( (clazz = classes[j++]) ) { //clazz = "nav-active", classes = ["nav-active"] classes[0]:"nav-active"
if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
cur += clazz + " "; //cur=" nav-item nav-active"
}
}
//indexOf() 方法可返回某个指定的字符串值在字符串中首次出现的位置。
//如果要检索的字符串值没有出现,则该方法返回 -1。
finalValue = jQuery.trim( cur );//finalValue = "nav-item nav-active", cur = " nav-item nav-active "
if ( elem.className !== finalValue ) {//elem = a.nav-item
elem.className = finalValue;//elem = a.nav-item.nav-active
}
}
}
}
return this;
},
/*jQuery.trim()函数用于去除字符串两端的空白字符。参数str不是字符串类型,该函数将自动将其
转为字符串(一般调用其toString()方法)。如果参数str为null或undefined,则返回空字符串("")。*/