属性函数jQuery attributes(上)

在改章节中,我们要主介绍属性函数的内容,自我感觉有个不错的建议和大家分享下

    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 );
};
当数参度长为0或只为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种人:懂得二进制的和不懂得二进制的。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值