首页 文章

jQuery Data vs Attr?

提问于
浏览
478

使用 data-someAttribute$.data$.attr 之间的用法有何不同?

我的理解是 $.data 存储在jQuery的 $.cache 中,而不是DOM中 . 因此,如果我想使用 $.cache 进行数据存储,我应该使用 $.data . 如果我想添加HTML5数据属性,我应该使用 $.attr("data-attribute", "myCoolValue") .

2 回答

  • 86

    如果要将数据从服务器传递到DOM元素,则应在元素上设置数据:

    <a id="foo" data-foo="bar" href="#">foo!</a>
    

    然后可以使用jQuery中的.data()访问数据:

    console.log( $('#foo').data('foo') );
    //outputs "bar"
    

    但是,当您使用数据在jQuery中的DOM节点上存储数据时,变量存储在节点对象上 . 这是为了容纳复杂的对象和引用,因为将数据存储在节点元素上作为属性只能容纳字符串值 .
    从上面继续我的例子:

    $('#foo').data('foo', 'baz');
    
    console.log( $('#foo').attr('data-foo') );
    //outputs "bar" as the attribute was never changed
    
    console.log( $('#foo').data('foo') );
    //outputs "baz" as the value has been updated on the object
    

    此外,数据属性的命名约定有一点隐藏的“陷阱”:
    HTML:

    <a id="bar" data-foo-bar-baz="fizz-buzz" href="#">fizz buzz!</a>
    

    JS:

    console.log( $('#bar').data('fooBarBaz') );
    //outputs "fizz-buzz" as hyphens are automatically camelCase'd
    

    带连字符的键仍然有效:
    HTML:

    <a id="bar" data-foo-bar-baz="fizz-buzz" href="#">fizz buzz!</a>
    

    JS:

    console.log( $('#bar').data('foo-bar-baz') );
    //still outputs "fizz-buzz"
    

    但是 .data() 返回的对象不会设置带连字符的键:

    $('#bar').data().fooBarBaz; //works
    $('#bar').data()['fooBarBaz']; //works
    $('#bar').data()['foo-bar-baz']; //does not work
    

    出于这个原因,我建议在javascript中避免使用带连字符的键 .

    对于HTML,请继续使用带连字符的表单 . HTML attributes are supposed to get ASCII-lowercased automatically,所以 <div data-foobar></div><DIV DATA-FOOBAR></DIV><dIv DaTa-FoObAr></DiV> 应该被视为相同,但为了获得最佳兼容性,小写形式应该是首选 .

    如果值与识别的模式匹配,.data()方法也将执行一些基本的自动转换:
    HTML:

    <a id="foo"
        href="#"
        data-str="bar"
        data-bool="true"
        data-num="15"
        data-json='{"fizz":["buzz"]}'>foo!</a>
    

    JS:

    $('#foo').data('str');  //`"bar"`
    $('#foo').data('bool'); //`true`
    $('#foo').data('num');  //`15`
    $('#foo').data('json'); //`{fizz:['buzz']}`
    

    这种自动转换功能非常便于实例化小部件和插件:

    $('.widget').each(function () {
        $(this).widget($(this).data());
        //-or-
        $(this).widget($(this).data('widget'));
    });
    

    如果您必须将原始值作为字符串,那么您将需要使用.attr()
    HTML:

    <a id="foo" href="#" data-color="ABC123"></a>
    <a id="bar" href="#" data-color="654321"></a>
    

    JS:

    $('#foo').data('color').length; //6
    $('#bar').data('color').length; //undefined, length isn't a property of numbers
    
    $('#foo').attr('data-color').length; //6
    $('#bar').attr('data-color').length; //6
    

    这是一个人为的例子 . 为了存储颜色值,我曾经使用数字十六进制表示法(即0xABC123),但值得注意的是,在1.7.2之前的jQuery版本中,hex被错误地解析,并且不再从jQuery 1.8 rc 1解析为数字 .

    jQuery 1.8 rc 1 changed the behavior of auto-casting . 之前,任何作为 Number 的有效表示的格式都将转换为 Number . 现在,只有数字值表示保持不变时才会自动转换 . 用一个例子可以很好地说明这一点 .
    HTML:

    <a id="foo"
        href="#"
        data-int="1000"
        data-decimal="1000.00"
        data-scientific="1e3"
        data-hex="0x03e8">foo!</a>
    

    JS:

    // pre 1.8    post 1.8
    $('#foo').data('int');        //    1000        1000
    $('#foo').data('decimal');    //    1000   "1000.00"
    $('#foo').data('scientific'); //    1000       "1e3"
    $('#foo').data('hex');        //    1000     "0x03e8"
    

    如果您计划使用替代数字语法来访问数值,请务必先将值转换为 Number ,例如使用一元 + 运算符 .
    JS(续):

    +$('#foo').data('hex'); // 1000
    
  • 722

    两者之间的主要区别在于它的存储位置和访问方式 .

    $.fn.attr将信息直接存储在元素中,这些属性在检查时是公开可见的,也可以从元素的本机API获得 .

    $.fn.data将信息存储在ridiculously obscure位置 . 它位于一个名为 data_user 的闭合局部变量中,该变量是本地定义的函数Data的一个实例 . 无法直接从jQuery外部访问此变量 .

    数据集 attr()

    • 可从 $(element).attr('data-name') 访问

    • 可从 element.getAttribute('data-name') 访问,

    • 如果该值的形式为 data-name ,也可从 $(element).data(name)element.dataset['name'] 以及 element.dataset.name 访问

    • 在检查时可见元件

    • 不能是对象

    数据集 .data()

    • 仅可从 .data(name) 访问

    • 无法从 .attr() 或其他任何地方访问

    • 在检查时未在元素上公开显示

    • 可以是对象

相关问题