HTML data-* VS jQuery data

了解HTML5的都知道html5新添加了data-* 的属性,下面是API文档说明

HTML5 is designed with extensibility in mind for data that should be associated with a particular element but need not have any defined meaning. data-* attributes allow us to store extra information on standard, semantic HTML elements without other hacks such as classList, non-standard attributes, extra properties on DOM, or setUserData.

首先先看下一个例子:

$("#div1").attr("data-userName","ryot");
$("#div2").attr("data-index-number","10");
console.log(document.getElementById('div1').dataset.userName);//undefined
console.log(document.getElementById('div1').dataset.username);//ryot
console.log(document.getElementById('div2').dataset.indexNumber);//10
console.log(document.getElementById('div2').dataset['index-number']);//uundefined
console.log(document.getElementById('div2').dataset.indexNumber + 10);//1010

由此可以看出HTML5的data的用法,首先html会把html节点的key转化为小写,如果多个以-连接的data-的属性
则会按照骆驼命名法则转化,同时值类型不会自动判断(与jQuery中data值可以自动判断类型).
当然在css中也可以使用:

list[data-columns='3'] {
  width: 400px;
}
list[data-columns='6'] {
  width: 200px;
}

jsbin中的例子

IE 11+ 才支持dataset属性,ie10及以下版本需要通过getAttribute()来访问,这相比于在js中使用
data存储效率要低的多

众所周知,jQuery中也有data可以存储数据,下面是jQuery的官方API解释:

Store arbitrary data associated with the specified element and/or return the value that was set.

大体意思是说:可以存储与特定的DOM元素关联的值,并可以取得设置的值

下面通过两个例子简单分析一下jQuery中data的使用看看跟HTML中的data区别

  • 1、下面通过jQuery的data设置值并取值
$("#div1").data("userName","ryot");
$("#div2").data("index-number","10");
console.log($("#div1").data("userName"));//ryot
console.log($("#div1").data("username"));//undefined
console.log($("#div2").data("indexNumber"));//10
console.log($("#div2").data('index-number'));//10
console.log($("#div2").data('indexNumber') + 10);//1010
  • 2、下面是通过HTML5的标签data-attribute设置,然后jQuery取值
$("#div1").attr("data-userName","ryot");
$("#div2").attr("data-index-number","10");
console.log($("#div1").data("userName"));//undefined
console.log($("#div1").data("username"));//ryot
console.log($("#div2").data("indexNumber"));//10
console.log($("#div2").data('index-number'));//10
console.log($("#div2").data('indexNumber') + 10);//20

通过上面的例子可以看出jQuery使用data的几个注意的地方:

  • 1.jQuery中data的key是“区分大小写的”,只是表面上的而已,实则另有玄机
  • 2.jQuery中data的key如果以“-”做链接的话,可以按照骆驼命名法则读取,也可以按照原始默认key
    读取
  • 3.jQuery中与HTML5标签同时赋予了同样的key时,会以jQuery中读取值优先

虽然通过代码测试可以看出这些特点,但是还是希望从jQuery(Version 2.1.4最新版)的源代码分析下原因:
1.首先是jQuery.data 赋值,源代码如下

data: function( elem, name, data ) {  
        return data_user.access( elem, name, data );  
    },  
access: function( owner, key, value ) {
        var stored;
        // In cases where either:
        //
        //   1. No key was specified
        //   2. A string key was specified, but no value provided
        //
        // Take the "read" path and allow the get method to determine
        // which value to return, respectively either:
        //
        //   1. The entire cache object
        //   2. The data stored at the key
        //
        if ( key === undefined ||
                ((key && typeof key === "string") && value === undefined) ) {
            stored = this.get( owner, key );
            return stored !== undefined ?
                stored : this.get( owner, jQuery.camelCase(key) );
        }
        // [*]When the key is not a string, or both a key and value
        // are specified, set or extend (existing objects) with either:
        //
        //   1. An object of properties
        //   2. A key and value
        //
        this.set( owner, key, value );
        // Since the "set" path can have two possible entry points
        // return the expected data based on which path was taken[*]
        return value !== undefined ? value : key;
    },
  set: function( owner, data, value ) {
        var prop,
            // There may be an unlock assigned to this node,
            // if there is no entry for this "owner", create one inline
            // and set the unlock as though an owner entry had always existed
            unlock = this.key( owner ),
            cache = this.cache[ unlock ];

        // Handle: [ owner, key, value ] args
        if ( typeof data === "string" ) {
            cache[ data ] = value;

        // Handle: [ owner, { properties } ] args
        } else {
            // Fresh assignments by object are shallow copied
            if ( jQuery.isEmptyObject( cache ) ) {
                jQuery.extend( this.cache[ unlock ], data );
            // Otherwise, copy the properties one-by-one to the cache object
            } else {
                for ( prop in data ) {
                    cache[ prop ] = data[ prop ];
                }
            }
        }
        return cache;
    },

通过jQuery的源码可以看出使用jQuery.data赋值时是将key-value与element做关联存储在cache的
缓存对象中。
下面看看如果在jQuery中和Html5 DOM节点中同时设置同样的data值时,jQuery是如何做的。注意看其中的
两行解释:

如果在内部没找到,则会试着去HTML5的标签上找data-* 的值

意思就是说一旦在使用jQuery设置过值,则会读取jQuery中的值,而不会遍历Html5的data-* 标签,所以
使用jQuery存值效率要高很多。

(下面是jQuery源码)

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 ) {
        name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();
        data = elem.getAttribute( name );

        if ( typeof data === "string" ) {
            try {
                data = data === "true" ? true :
                    data === "false" ? false :
                    data === "null" ? null :
                    // Only convert to a number if it doesn't change the string
                    +data + "" === data ? +data :
                    rbrace.test( data ) ? jQuery.parseJSON( data ) :
                    data;
            } catch( e ) {}

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

Only convert to a number if it doesn't change the string

其中的这句也就解释了为什么HTML5标签中的data-* 通过jQuery.data取值是会自动类型匹配了。


最有意思的就是取值了,上面我们知道html5 节点的属性值均会自动改为小写。但是jQuery存储读取
则是以骆驼法则来读取设置值的:
简单来说就是
:$("#div1").data("userName","mike");
等同于
$("#div1").data("user-name","mike");
所以在取值的时候两种方式取得值为一样的,这就是所谓看似区分大小写的真面目。
(下面是jQuery源码)

// Convert dashed to camelCase; used by the css and data modules
    // Support: IE9-11+
    // Microsoft forgot to hump their vendor prefix (#9572)
    camelCase: function( string ) {
        return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
    },

    nodeName: function( elem, name ) {
        return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
    },

以上如有错误的地方,欢迎批评指正。

已收藏到github中 http://ryotlee.github.io/blog/2015/10/21/HTML%20data-*%20VS%20jQuery%20data/

转载于:https://www.cnblogs.com/muzizone/p/4743903.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值