jQuery属性操作(四)
通过阅读jQuery为属性操作封装的基本方法和为处理兼容性问题提供的hooks,发现jQuery在属性操作方面并没有做过多的设计,只是处理一下兼容性问题,然后调用基础的DOM操作方法。以下是对JQuery提供的基础方法的阅读:
jQuery.fn.extend({
// 调用access方法进行参数整理之后调用$.attr方法
attr: function( name, value ) {
return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 );
},
// 遍历jQuery对象中的所有元素,对每一个元素调用$.removeAttr方法
removeAttr: function( name ) {
return this.each(function() {
jQuery.removeAttr( this, name );
});
},
// 调用access方法进行参数整理之后调用$.attr方法
prop: function( name, value ) {
return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 );
},
// 遍历jQuery对象中的所有元素,直接删除该元素的相应属性
removeProp: function( name ) {
return this.each(function() {
// 对html上的属性和DOM属性进行一些匹配转换
delete this[ jQuery.propFix[ name ] || name ];
});
},
addClass: function( value ) {
var classes, elem, cur, clazz, j,
i = 0,
len = this.length,
proceed = typeof value === "string" && value;
// 如果value是function。
if ( jQuery.isFunction( value ) ) {
return this.each(function( j ) {
// 执行该function并将结果作为参数再次调用addClass
jQuery( this ).addClass( value.call( this, j, this.className ) );
});
}
// 如果value是字符串
if ( proceed ) {
// 如果字符串中有空格,说明添加的不只是一个class,用空格将字符串转换成数组
classes = ( value || "" ).match( core_rnotwhite ) || [];
// 遍历jQuery中的每一个DOM元素
for ( ; i < len; i++ ) {
// 拿到当前元素
elem = this[ i ];
// 拿到当前元素上的所有当前class
cur = elem.nodeType === 1 && ( elem.className ?
( " " + elem.className + " " ).replace( rclass, " " ) :
" "
);
// 如果是元素节点(这里看起来像是判断该元素是不是已经有class,其实只是判断是不是元素节点)
if ( cur ) {
j = 0;
// 遍历用户传入的所有class
while ( (clazz = classes[j++]) ) {
// 如果当前元素已经有的class中没有用户传入的class,则在已经有的class中增加用户传入的class
if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
cur += clazz + " ";
}
}
// 删除最后得到的class字符串前后两端的空格之后赋值给当前元素的className属性
elem.className = jQuery.trim( cur );
}
}
}
// 为了实现链式操作,返回this
return this;
},
// 删除class和增加class的逻辑基本一致
removeClass: function( value ) {
var classes, elem, cur, clazz, j,
i = 0,
len = this.length,
proceed = arguments.length === 0 || typeof value === "string" && value;
if ( jQuery.isFunction( value ) ) {
return this.each(function( j ) {
jQuery( this ).removeClass( value.call( this, j, this.className ) );
});
}
if ( proceed ) {
classes = ( value || "" ).match( core_rnotwhite ) || [];
for ( ; i < len; i++ ) {
elem = this[ i ];
cur = elem.nodeType === 1 && ( elem.className ?
( " " + elem.className + " " ).replace( rclass, " " ) :
""
);
if ( cur ) {
j = 0;
while ( (clazz = classes[j++]) ) {
// 只有此处不同,是从已经有的class中删除用户传入的class
while ( cur.indexOf( " " + clazz + " " ) >= 0 ) {
cur = cur.replace( " " + clazz + " ", " " );
}
}
elem.className = value ? jQuery.trim( cur ) : "";
}
}
}
return this;
},
// toggleClass是通过调用addClass和removeClass来实现的。
toggleClass: function( value, stateVal ) {
var type = typeof value;
// stateval是一个boolean值,当为true时,发挥addClass的作用,当为false时,发挥removeClass的作用
if ( typeof stateVal === "boolean" && type === "string" ) {
return stateVal ? this.addClass( value ) : this.removeClass( value );
}
// 如果是个function,执行之后结果作为参数继续调用toggleClass
if ( jQuery.isFunction( value ) ) {
return this.each(function( i ) {
jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );
});
}
// toggleClass的主体部分
return this.each(function() {
if ( type === "string" ) {
var className,
i = 0,
self = jQuery( this ),
classNames = value.match( core_rnotwhite ) || [];
// 遍历所有用户传入的class
while ( (className = classNames[ i++ ]) ) {
// 调用hasClass方法,如果有这个class就删除
if ( self.hasClass( className ) ) {
self.removeClass( className );
// 如果没有就添加
} else {
self.addClass( className );
}
}
// 如果用户在调用toggleClass时没有传入class,则对已经有的所有class进行toggle
} else if ( type === core_strundefined || type === "boolean" ) {
if ( this.className ) {
// 当删除class时,为了能够在添加回来,将其储存到jQuery内部使用的data对象中
data_priv.set( this, "__className__", this.className );
}
// 如果当前元素有class或者没有value(说明没有传value,而是传入了stateVal,这个时候是想要删除class),清空className,否则从缓存中拿出来添 // 加给className属性
this.className = this.className || value === false ? "" : data_priv.get( this, "__className__" ) || "";
}
});
},
hasClass: function( selector ) {
var className = " " + selector + " ",
i = 0,
l = this.length;
for ( ; i < l; i++ ) {
// 如果是元素节点,替换掉空格、空行等之后看是否存在用户传入的class
if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) {
// 如果有,返回true
return true;
}
}
// 默认false
return false;
},
// 得到或删除元素值
val: function( value ) {
var hooks, ret, isFunction,
// 只对第一个元素进行操作
elem = this[0];
// 如果没有参数,则说明是要取元素值
if ( !arguments.length ) {
if ( elem ) {
// 看看该元素是否有对应的hooks
hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];
// 如果有对应的hooks,并且hooks中有get方法,则调用get方法。如果get方法返回了不是undefined的值,则返回该值。
if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
return ret;
}
// 如果不存在hooks,则正常处理,直接拿到元素的value
ret = elem.value;
return typeof ret === "string" ?
ret.replace(rreturn, "") :
ret == null ? "" : ret;
}
return;
}
// 看参数是否是function
isFunction = jQuery.isFunction( value );
// 处理有参数的情况(设置元素值)
return this.each(function( i ) {
var val;
// 如果不是元素节点,直接返回
if ( this.nodeType !== 1 ) {
return;
}
// 如果是function,将执行结果赋值个val
if ( isFunction ) {
val = value.call( this, i, jQuery( this ).val() );
} else {
val = value;
}
// 如果val为null,则赋值为空字符串
if ( val == null ) {
val = "";
// 如果是number,转换成字符串
} else if ( typeof val === "number" ) {
val += "";
// 如果是数组,呃。。
} else if ( jQuery.isArray( val ) ) {
val = jQuery.map(val, function ( value ) {
return value == null ? "" : value + "";
});
}
// 看是否有对应的hooks
hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
// 如果没有对应的hooks,或者hooks中没有set方法,或者执行hooks的set方法返回的是undefined(这里其实默默的执行了hooks的set方法)
if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
// 正常赋值
this.value = val;
}
});
}
});
jQuery属性操作(四)的更多相关文章
- jquery——属性操作、特殊效果
1. attr().prop() 取出或者设置某个属性的值 <!DOCTYPE html> <html lang="en"> <head> &l ...
- jQuery源代码学习之八——jQuery属性操作模块
一.jQuery属性模块整体介绍 jQuery的属性操作模块分四个部分:html属性操作,dom属性操作,类样式操作,和值操作. html属性操作(setAttribute/getAttribute) ...
- python全栈开发day48-jqurey自定义动画,jQuery属性操作,jQuery的文档操作,jQuery中的ajax
一.昨日内容回顾 1.jQuery初识 1).使用jQuery而非JS的六大理由 2).jQuery对象和js对象转换 3).jQuery的两大特点 4).jQuery的入口函数三大写法 5).jQu ...
- jQuery属性操作
jQuery 的属性操作的核心部分其实就是对底层 getAttribute().setAttributes()等方法的一系列兼容性处理 ...if ( notxml ) { name = name.t ...
- jQuery 属性操作和CSS 操作
如有在jQuery方法中涉及到函数,此函数必定会返回一个数值(函数由于运行次数不同触发一些不同效果) jQuery 属性操作方法(以下方法前些日子学习过,不再赘述) addClass() attr() ...
- jQuery属性操作(二)
挂载到$上的几个属性操作方法分析,发现属性操作用到了sizzle封装的方法 attr: function( elem, name, value ) { var hooks, ret, ...
- jQuery属性操作(一)
下载了jQuery的UI组件,发现内容还挺多的,还是决定先把jQuery的源码看完一遍之后再涉足UI组件.考虑到队列和动画使用较少,特别是动画,基本开始使用css3完成.因此暂时略过,开始看jQuer ...
- web前端----jQuery属性操作
知识点总结 1.属性 属性(如果你的选择器选出了多个对象,那么默认只会返回出第一个属性). attr(属性名|属性值) - 一个参数是获取属性的值,两个参数是设置属性值 - 点击加载图片示例 remo ...
- Jquery属性操作(入门二)
********JQuery属性相关的操作******** 1.属性 属性(如果你的选择器选出了多个对象,那么默认只会返回出第一个属性). attr(属性名|属性值) - 一个参数是获取属性的值,两个 ...
随机推荐
- ASP.NET 网站超时跳转到登录界面
利用actionFilter过滤器实现,超时跳转到登录界面 /// <summary> /// 登录超时跳转至登录界面 /// </summary> public class ...
- EF5+MVC4系列(1) Podwerdesigner15.1设计数据库;PD中间表和EF实体模型设计器生成中间表的区别;EF5.0 表关系插入数据(一对多,多对多)
在上一篇文章中, http://www.cnblogs.com/joeylee/p/3790980.html 我们用 PD15.1 来设计了数据库,并且生成 了sql数据库,现在我们用 vs2013 ...
- DATGRIDVIEW如何不选择第一行,第一列
DataBindingComplete事件中写 ClearSelection();
- java注解自定义使用
Java提供了4种注解,专门负责新注解的创建: @Target: 表示该注解可以用于什么地方,可能的ElementType参数有:CONSTRUCTOR:构造器的声明FIELD:域声明(包括enum实 ...
- Android 知识梳理
说明:本篇博客只是一个知识整理,因为网上对于Android的知识介绍足够多,因此我不再写相关文章(主要是因为我写的不如人家好),所以所有文章均来自网络,不贴原文章,只提供连接,因此本文旨在减少你对相关 ...
- 安卓开发笔记——关于AsyncTask的使用
在安卓开发中,我们经常要进行一些耗时操作,比如数据库操作,获取网络资源,读取内存文件等等,当我们在处理这些耗时操作的时候,如果我们直接在UI主线程进行,那么可能会导致阻塞UI主线程,使得UI界面卡顿, ...
- 最新Java面试题及答案整理
基础篇 一.基本功 面向对象特征 封装,继承,多态和抽象 1. 封装 封装给对象提供了隐藏内部特性和行为的能力.对象提供一些能被其他对象访问的方法来改变它内部的数据.在 Java 当中,有 3 种修饰 ...
- C#操作共享文件夹
public class NetFileShare { public NetFileShare() { } public static bool connectState(string path) { ...
- spring核心之AOP学习总结一
一:springAOP前置通知.后置通知以及最终通知 前置通知就是在切入点前面执行方面体,后置就是在后面,最终就是返回之后. 下面以一个日志记录的案例介绍: 1:创建controller类 /** * ...
- vs2012更改默认开发环境
1.在菜单栏里找到“Tools”(工具),选择下面的“Import and Export Settings”(导入和导出设置),如图1所示: 图1 2.弹出如下界面,按提示选择你需要 ...