在改章节中,我们要主介绍属性函数的内容,自我感觉有个不错的建议和大家分享下
jQuery attributes供给了文档节点的属性操纵法方。
为了更好的解理,我们先决解jQuery core中的access数参设置函数。
jQuery.access
jQuery.access是一个专用于数参设置以及读取的法方。
在jQuery链式操纵中我们对BigInteger的值获得是通过法方val来获得的,很显然此时val前面不能再链式操纵了。所以:
如果要读取数参值,那么这个操纵就不能链式操纵。
/************************* * elems: 接受操纵的素元组 * fn: 设置或读取函数 * key: 要设置的属性 * value: 要设置的值,也可所以函数 * chainable: 否是可以链式操纵,是即读还是写操纵 * emptyGet: 读取如果为空用什么表现 * raw: value否能直接传给fn,如果的确就是想将属性设置成函数value,那么要把这个值设成true */ jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) { var i = 0, length = elems.length, //key否是为空 bulk = key == null; // 设置多许属性 if ( jQuery.type( key ) === "object" ) { chainable = true; for ( i in key ) { //代迭执行设置一个值 jQuery.access( elems, fn, i, key[i], true, emptyGet, raw ); } // 只设置一个值 } else if ( value !== undefined ) { chainable = true; //如果value不是函数 if ( !jQuery.isFunction( value ) ) { raw = true; } //如果key为空 if ( bulk ) { // 如果raw为true,即value不是函数 if ( raw ) { //执行fn,其this为elems,数参为value fn.call( elems, value ); fn = null; // 如果value是函数 } else { //用bulk保存fn bulk = fn; //将fn酿成特定情势 fn = function( elem, key, value ) { return bulk.call( jQuery( elem ), value ); }; } } //如果fn存在 if ( fn ) { //历遍有所elems for ( ; i < length; i++ ) { //value是函数则行运fn(elem, key, value.call(elem, i, fn(elem, key))) //value非函数则行运fn(elem, key, value) fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) ); } } } //如果是可链式操纵的则返回elems return chainable ? elems : // 否则则是读取操纵 bulk ? fn.call( elems ) : // 否则如果度长不为0,则返回fn( elems[0], key ),否则返回空 length ? fn( elems[0], key ) : emptyGet; }
jQuery官方文档没有该函数,应该说这是jQuery的一个部内具工。要主是为了实现jQuery中设置与读取复用性逻辑以及其内循环的,也就是为了节俭写代码而已。
jQuery.fn.attr()
fn也就是jQuery实例对象的法方集。
fn中的法方attr也就是我们经常使用的attr法方。
如获得em标签的title属性:
var title = $("em").attr("title");
jQuery.fn.attr = function( name, value ) { return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 ); };
而这里用的设置函数是jQuery.attr,即现实行运时会行运jQuery.attr(elem, name, value)。
那么jQuery.attr是如何实现的呢?
/*************************** * elem: 要操纵的素元 * name: 素元的属性名 * value: 要变改的值 */ jQuery.attr = function( elem, name, value ) { var ret, hooks, notxml, nType = elem.nodeType; // 不处置text,comment,attribute节点 if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { return; } // 如果属性不支持则用使jQuery.prop if ( typeof elem.getAttribute === "undefined" ) { return jQuery.prop( elem, name, value ); } //否是不是XML notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); // 如果不是XML if ( notxml ) { //那么有所属性名应当是小写 name = name.toLowerCase(); //如果属性义定了,那么就住抓须要的钩子,决解IE6-9的关相问题 hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook ); } //如果value不是没有义定,即写入操纵 if ( value !== undefined ) { //如果value为空,则是删除操纵 if ( value === null ) { jQuery.removeAttr( elem, name ); //如果钩子有set法方,则设置了以后,返回其值 } else if ( hooks && notxml && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { return ret; //否则用使setAttribute法方 } else { elem.setAttribute( name, value + "" ); return value; } //如果是读取操纵,如果钩子有get法方,则通过get失掉返回值 } else if ( hooks && notxml && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { return ret; //如果没有get法方 } else { // IE9+中Flash对象没有.getAttrubute法方,判断止防错误 if ( typeof elem.getAttribute !== "undefined" ) { ret = elem.getAttribute( name ); } // 返回undefined或则值 return ret == null ? undefined : ret; } };
jQuery.removeAttr
removeAttr = function( elem, value ) { var name, propName, i = 0, //分解value成为多个属性的数组 attrNames = value && value.match( core_rnotwhite ); //如果有要删除的属性名 if ( attrNames && elem.nodeType === 1 ) { //历遍有所属性名 while ( (name = attrNames[i++]) ) { //看看需不需要用propFix来修改名字,不必直接用name propName = jQuery.propFix[ name ] || name; // 如果属性是尔布量先改成false if ( rboolean.test( name ) ) { elem[ propName ] = false; } //删除属性 elem.removeAttribute( name ); } } };
jQuery.propFix干了什么呢?
现实只是修改一下属性名,比如很多人爱好用class来表现css类名,但现实上是className。
jQuery.propFix = { tabindex: "tabIndex", readonly: "readOnly", "for": "htmlFor", "class": "className", maxlength: "maxLength", cellspacing: "cellSpacing", cellpadding: "cellPadding", rowspan: "rowSpan", colspan: "colSpan", usemap: "useMap", frameborder: "frameBorder", contenteditable: "contentEditable" };
jQuery.fn.removeAttr
这个函数实现比较简略,只是用each法方来调用jQuery.removeAttr而已。
jQuery.fn.removeAttr = function( name ) { return this.each(function() { jQuery.removeAttr( this, name ); }); };
jQuery.fn.prop
jQuery.fn.prop = function( name, value ) { return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 ); };
可见jQuery.fn.prop和jQuery.fn.attr差不多。
jQuery.prop
jQuery.prop = function( elem, name, value ) { var ret, hooks, notxml, nType = elem.nodeType; if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { return; } notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); if ( notxml ) { // 修复name和钩子 name = jQuery.propFix[ name ] || name; hooks = jQuery.propHooks[ name ]; } if ( value !== undefined ) { if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { return ret; } else { return ( elem[ name ] = value ); } } else { if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { return ret; } else { return elem[ name ]; } } };
由于和jQuery.attr差不多,就不备注了。
jQuery.fn.removeProp
removeProp = function( name ) { name = jQuery.propFix[ name ] || name; return this.each(function() { // try/catch handles cases where IE balks (such as removing a property on window) try { this[ name ] = undefined; delete this[ name ]; } catch( e ) {} }); };
removeProp对相简略些,只是通过each将有所素元的属性设为undefined然后delete掉而已。
Attrubute和Property
从源代码我们可以发明,jQuery.attr如果找不到应相的法方会用使jQuery.prop。
jQuery 1.6入加jQuery.prop法方后,对很多人来讲可能本根没啥用,因为用jQuery.attr法方肯定是对的。
但jQuery.attr和jQuery.prop到底别差在哪里呢?
这是Attrubute和Property的别差。
jQuery.attr法方会处置Attrubute和Property,但jQuery.prop只处置Property。
虽然这两个单词都可以翻译成“属性”,但是这两个现实上是不同的。
我们用一个例子来明说这个问题:
function Demo(){ var attrs = {}; this.name = "Bob"; this.setAttr = function(name, value){ attrs[name] = value; return value; } this.getAttr = function(name){ return attrs[name]; } }
var i = new Demo(); i.name //Property i.setAttr("name", "Tom"); i.getAttr("name") //Attrubute
所以jQuery文档中对jQuery.prop的释解是:获得在配匹的素元会合的第一个素元的属性值。
文章结束给大家分享下程序员的一些笑话语录: 这个世界上只有10种人:懂得二进制的和不懂得二进制的。