• jQuery attr() 源码解读


    我们知道,$().attr()实质上是内部调用了jQuery.access方法,在调用时jQuery.attr作为回调传入。在通过种种判断(参看jQuery.access()方法)之后,取值和赋值最后调用了这个jQuery.attr方法。

    所以,关键是看jQuery.attr这里怎么走了~~

    源码如下:

       attr: function( elem, name, value ) {
            var hooks, ret,
                nType = elem.nodeType;
            //如果elem不存在,或者是文本、注释、属性节点
            // don't get/set attributes on text, comment and attribute nodes
            if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
                return;
            }
    
            // Fallback to prop when attributes are not supported
            if ( typeof elem.getAttribute === core_strundefined ) {//如果elem不支持getAttribute 比如document或者文档碎片
                return jQuery.prop( elem, name, value );//调用jQuery.prop方法
            }
    
            // All attributes are lowercase
            // Grab necessary hook if one is defined
            //
            if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {//elem不是标签或者elem不在xml中
                name = name.toLowerCase();//属性名大写
                hooks = jQuery.attrHooks[ name ] ||
                    ( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook );//jQuery.attrHooks.type
            }
    
            if ( value !== undefined ) {//赋值
    
                if ( value === null ) {//如果设的值为null,相当于移除attr ,比如.attr('checked',null);
                    jQuery.removeAttr( elem, name );
    
                } else if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {//调用钩子的set方法
                    return ret;
    
                } else {
                    elem.setAttribute( name, value + "" );//如果value是数值,隐式转为字符串
                    return value;
                }
    
            } else if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {//调用钩子的get
                return ret;
    
            } else {//取值
                ret = jQuery.find.attr( elem, name );//调用Sizzle.attr  因为jquery中有一句:jQuery.find = Sizzle;
                //将null值修正为undefined
                // Non-existent attributes return null, we normalize to undefined
                return ret == null ?
                    undefined :
                    ret;
            }
        }

    从上面的代码看,有7个走向:

    1、return

    2、jQuery.prop

    3、jQuery.removeAttr

    4、attrHooks.set

    5、elem.setAttribute

    6、attrHooks.get

    7、Sizzle.attr

    前面5个都是设置值,6和7是读值。

    2和3以后会读到,这里不提,先看看Sizzle.attr中是怎么一回事吧^^

        Sizzle.attr = function( elem, name ) {
        // Set document vars if needed
        if ( ( elem.ownerDocument || elem ) !== document ) {//如果不是当前document
            setDocument( elem );//不知道干嘛 考虑iframe的情况?
        }
    
        //Expr.attrHandle是一个对象,包含了
        //async autofocus autoplay checked controls defer disabled hidden ismap loop 
        //multiple open readonly required scoped selected 等自定义方法(属性)
        var fn = Expr.attrHandle[ name.toLowerCase() ],
            // Don't get fooled by Object.prototype properties (jQuery #13807)
    
            //hasOwn 就是hasOwnProperty 
            //所以这个hasOwn.call( Expr.attrHandle, name.toLowerCase() ) 是在判断传入的属性名是不是这个对象的
            //自定义属性,而不是原型上的属性
            //val为调用自定义方法的结果或者undefined
            val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
                fn( elem, name, !documentIsHTML ) :
                undefined;
    
        //如果val为undefined
            //如果(support.attributes为真或者document不是html),返回elem.getAttribute( name )的值
            //否则 val为 elem.getAttributeNode(name))的值
                //如果val为真,并且val.specified为真,返回val.value
                //否则返回null
        //否则返回val
        return val === undefined ?
            support.attributes || !documentIsHTML ?
                elem.getAttribute( name ) :
                (val = elem.getAttributeNode(name)) && val.specified ?
                    val.value :
                    null :
            val;
    };

    复杂的三元运算符看得头都大了有木有,好吧,这里能看到,取值用getAttribute或者getAttributeNode。

    再看attrHooks是一些什么内容:

        attrHooks: {
            type: {
                set: function( elem, value ) {
                    if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) {
                        // Setting the type on a radio button after the value resets the value in IE6-9
                        // Reset value to default in case type is set after value during creationvar val = elem.value;
                        elem.setAttribute( "type", value );
                        if ( val ) {
                            elem.value = val;
                        }
                        return value;
                    }
                }
            }
        }

    从这里可以看到,attrHooks与设置input标签的type值有关,恩,如果设置的值为radio的时候,注意下。

  • 相关阅读:
    洛谷 3393 逃离僵尸岛
    洛谷 3275 [SCOI2011]糖果
    SP1437 Longest path in a tree(树的直径)
    洛谷2483 k短路([SDOI2010]魔法猪学院)
    洛谷3243 [HNOI2015]菜肴制作
    洛谷 4568 [JLOI2011] 飞行路线
    [USACO08DEC]在农场万圣节Trick or Treat on the Farm
    手机端table表格bug
    手机端左右滑动效果
    去掉手机端延迟300ms
  • 原文地址:https://www.cnblogs.com/qianlegeqian/p/4119896.html
Copyright © 2020-2023  润新知