优美编程

JQuery源码阅读0=>data同级

2018-04-30  本文已影响2人  小遁哥

dataUser存储用户的数据
dataPriv 存储JQ自己的数据

0 JQuery.fn.extend.data

data: function( key, value ) {
    var i, name, data,
        elem = this[ 0 ],
        //返回NamedNodeMap对象,属性节点的集和,例如[class,data-name]
        attrs = elem && elem.attributes;

    // Gets all values
    //不传key意味得到全部  
    if ( key === undefined ) {
        if ( this.length ) {
            //得到全部的数据
            data = dataUser.get( elem );

            if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) {
                
                i = attrs.length;
                while ( i-- ) {

                    // Support: IE 11 only
                    // The attrs elements can be null (#14894)
                    if ( attrs[ i ] ) {
                        name = attrs[ i ].name;
                        if ( name.indexOf( "data-" ) === 0 ) {
                            //将已-分隔的写法转换为驼峰写法,并去除私有前缀(ms-)
                            name = camelCase( name.slice( 5 ) );
                           //当data[ name ]为undefined且elem.getAttribute("data-"+name)有值时 会执行dataUser.set方法。
  这时data值也会改变,因为data指向的内存地址没有改变,但内存里存储的数据发生了变化
                            dataAttr( elem, name, data[ name ] );
                        }
                    }
                }
                dataPriv.set( elem, "hasDataAttrs", true );
            }
        }

        return data;
    }

    // Sets multiple values
    //设置多个值{name:"123",age:12}
    if ( typeof key === "object" ) {
                    //this是Jquery对象
        return this.each( function() {
                            //this 是DOM对象
            dataUser.set( this, key );
        } );
    }

    return access( this, function( value ) {
        var data;

        // The calling jQuery object (element matches) is not empty
        // (and therefore has an element appears at this[ 0 ]) and the
        // `value` parameter was not undefined. An empty jQuery object
        // will result in `undefined` for elem = this[ 0 ] which will
        // throw an exception if an attempt to read a data cache is made.
        if ( elem && value === undefined ) {

            // Attempt to get data from the cache
            // The key will always be camelCased in Data
            data = dataUser.get( elem, key );
            if ( data !== undefined ) {
                return data;
            }

            // Attempt to "discover" the data in
            // HTML5 custom data-* attrs
            data = dataAttr( elem, key );
            if ( data !== undefined ) {
                return data;
            }

            // We tried really hard, but the data doesn't exist.
            return;
        }

        // Set the data...
        this.each( function() {

            // We always store the camelCased key
            dataUser.set( this, key, value );
        } );
    }, null, value, arguments.length > 1, null, true );
},

0.1 dataAttr

function dataAttr( elem, key, data ) {
var name;

// If nothing was found internally, try to fetch any
// data from the HTML5 data-* attribute
if ( data === undefined && elem.nodeType === 1 ) {
    // rmultiDash = [A-Z]/g $&等同于是RegExp对象的静态属性lastMatch,是指匹配的片段,把驼峰写法转换为-分隔
    name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase();
    data = elem.getAttribute( name );

    if ( typeof data === "string" ) {
        try {
            //进行类型转换 比如"true"=>true
            data = getData( data );
        } catch ( e ) {}

        // Make sure we set the data so it isn't changed later
        //放入elem的dataUser中
        dataUser.set( elem, key, data );
    } else {
        data = undefined;
    }
}
return data;

}

0.2 getData

function getData( data ) {
if ( data === "true" ) {
    return true;
}

if ( data === "false" ) {
    return false;
}

if ( data === "null" ) {
    return null;
}

// Only convert to a number if it doesn't change the string
//+data 将字符串数字("123")转换数字
if ( data === +data + "" ) {
    return +data;
}
///^(?:\{[\w\W]*\}|\[[\w\W]*\])$/ ,简单的json验证 列入<p class="shadow" data-name="{&quot;klo&quot;:123}"></p>
if ( rbrace.test( data ) ) {
    return JSON.parse( data );
}

return data;

}

1 JQuery.fn.extend.removeData

removeData: function( key ) {
    return this.each( function() {
        dataUser.remove( this, key );
    } );
}
上一篇下一篇

猜你喜欢

热点阅读