ข้อมูล jQuery เทียบกับ Attr?


513

การใช้งานระหว่าง$.dataและ$.attrเมื่อใช้แตกต่างกันdata-someAttributeอย่างไร

ความเข้าใจของฉันคือที่$.dataเก็บไว้ภายใน jQuery $.cacheไม่ใช่ DOM ดังนั้นถ้าผมต้องการที่จะใช้สำหรับการจัดเก็บข้อมูลที่ฉันควรใช้$.cache $.dataถ้าผมต้องการที่จะเพิ่ม HTML5 $.attr("data-attribute", "myCoolValue")ข้อมูลแอตทริบิวต์ฉันควรใช้


5
โปรดอ่านสิ่งนี้: forum.jquery.com/topic/when-to-use-attr-vs-data
Baz1nga

14
@zzz ยกเว้นว่ามันดูเหมือนจะไม่ตอบคำถาม ...
sdleihssirhc

2
จริงๆแล้วมันทำทางอ้อม การติดวัตถุผ่านทางattr()อาจทำให้หน่วยความจำรั่ว (อย่างน้อยก็ใน IE) ในขณะที่ใช้งานdata()นั้นปลอดภัย เขาพูดถึงเรื่องนี้ในคำตอบของเขาแม้ว่าเขาจะไม่ได้ออกมาพูดอย่างชัดเจน ข้อมูลเพิ่มเติมเกี่ยวกับเอกสาร jQuery (ดูที่ "หมายเหตุเพิ่มเติม"): api.jquery.com/attr
ken

6
@John B เพียงแค่ FYI (แม้ว่านี่จะเก่าแล้ว) แอตทริบิวต์ของข้อมูลdata-someAttributeนั้นไม่ถูกต้อง ตามสเป็คอนุญาตให้ใช้ตัวพิมพ์เล็กเท่านั้น คุณจะพบกับปัญหาแปลก ๆ มากมายโดยใช้ตัวอักษรพิมพ์ใหญ่
เคน

1
@AdrienBe มีการอ้างอิงจำนวนมากที่ค้นพบได้ง่ายผ่านการค้นหา แต่เนื่องจากฉันเบื่อคุณไปเลย: stackoverflow.com/a/22753630/84473
ken

คำตอบ:


748

หากคุณกำลังส่งข้อมูลไปยังองค์ประกอบ DOM จากเซิร์ฟเวอร์คุณควรตั้งค่าข้อมูลในองค์ประกอบ:

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

ข้อมูลนั้นสามารถเข้าถึงได้โดยใช้.data()ใน jQuery:

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

แต่เมื่อคุณจัดเก็บข้อมูลบนโหนด DOM ใน jQuery ใช้ข้อมูลตัวแปรจะถูกเก็บไว้บนโหนดวัตถุ นี่คือการรองรับวัตถุที่ซับซ้อนและการอ้างอิงเป็นการจัดเก็บข้อมูลในองค์ประกอบโหนดเป็นคุณลักษณะที่จะรองรับค่าสตริงเท่านั้น

ดำเนินการต่อจากตัวอย่างด้านบน:
$('#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

นอกจากนี้แผนการตั้งชื่อสำหรับแอตทริบิวต์ข้อมูลมีบิตของ "gotcha" ที่ซ่อนอยู่:

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 ที่ควรจะได้รับ ASCII-lowercased โดยอัตโนมัติดังนั้น<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) แต่มันก็คุ้มค่าที่จะสังเกตว่าเลขฐานสิบหกนั้นได้รับการแยกวิเคราะห์อย่างไม่ถูกต้องในรุ่น jQuery ก่อน 1.7.2และจะไม่ถูกวิเคราะห์Numberเป็น jQuery 1.8 rc 1 อีกต่อไป

jQuery 1.8 RC 1 การเปลี่ยนแปลงพฤติกรรมของอัตโนมัติหล่อ ก่อนที่จะรูปแบบใด ๆ ที่เป็นตัวแทนที่ถูกต้องของจะถูกโยนไป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อันดับแรกเช่นกับ+โอเปอเรเตอร์unary

JS (ต่อ):
+$('#foo').data('hex'); // 1000

17
@vitorbal ในขณะที่สิ่งนี้เป็นจริงวัตถุที่ส่งกลับโดย.data()จะไม่มีชุดรูปแบบยัติภังค์ดังนั้น$('#bar').data('foo-bar-baz')จะทำงาน แต่$('#bar').data()['foo-bar-baz']จะไม่ ด้วยเหตุนี้ฉันจึงแนะนำให้ผู้คนหลีกเลี่ยงการใช้ฟอร์มยัติภังค์
zzzzBov

1
ตกลงตอนนี้ฉันเห็นสิ่งที่คุณหมายถึง ไม่ทราบรายละเอียดเล็ก ๆ น้อย ๆ ขอบคุณสำหรับการอัปเดต :)
vitorbal

1
@SableFoste ลิงค์ไหน? api.jquery.com/dataเป็นลิงก์ที่ถูกต้องสำหรับวิธีการและไม่เปลี่ยนแปลงเท่าที่ฉันทราบ
zzzzBov

1
ฉันชอบ, foo, bar, baz, fizz, buzz เพิ่มเติม: D
Usman Younas

1
รักทุกบรรทัด
Foo Bar

108

ความแตกต่างที่สำคัญระหว่างสองคือที่เก็บและวิธีการเข้าถึง

$.fn.attr เก็บข้อมูลโดยตรงกับองค์ประกอบในแอททริบิวต์ที่เปิดเผยต่อสาธารณะเมื่อทำการตรวจสอบและสามารถดูได้จาก API เนทีฟขององค์ประกอบ

$.fn.dataเก็บข้อมูลในปิดบังขันสถานที่ มันตั้งอยู่ในตัวแปรปิดท้องถิ่นที่เรียกว่าdata_userซึ่งเป็นตัวอย่างของฟังก์ชั่นที่กำหนดไว้ในท้องถิ่นข้อมูล ตัวแปรนี้ไม่สามารถเข้าถึงได้จากนอก 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()หรือที่อื่น ๆ
  • ไม่ปรากฏต่อสาธารณะในองค์ประกอบเมื่อทำการตรวจสอบ
  • สามารถเป็นวัตถุ

2
ใช่คำถามหลักของฉันคือที่เก็บข้อมูลนี้ดังนั้นขอขอบคุณสำหรับข้อมูล!
Max Wilder

2
นอกจากนี้ยัง.attr()เป็นวิธีที่จะไปหากหลังจากนั้นคุณต้องการใช้ข้อมูลเป็นตัวเลือก ( .data()จะไม่พบ; ดูcodepen.io/anon/pen/EvawPV?editors=1011 )
Kamafeather

1

คุณสามารถใช้data-*แอตทริบิวต์เพื่อฝังข้อมูลที่กำหนดเองได้ data-*คุณลักษณะที่ช่วยให้เรามีความสามารถในการข้อมูลที่กำหนดเองฝังแอตทริบิวต์องค์ประกอบ HTML ทั้งหมด

.data()วิธีการjQuery อนุญาตให้คุณรับ / ตั้งค่าข้อมูลประเภทใด ๆ ไปยังองค์ประกอบ DOM ในวิธีที่ปลอดภัยจากการอ้างอิงแบบวงกลมและจากการรั่วไหลของหน่วยความจำ

.attr()วิธีการjQuery รับ / ชุดค่าแอตทริบิวต์สำหรับองค์ประกอบแรกเท่านั้นในชุดที่ตรงกัน

ตัวอย่าง:

<span id="test" title="foo" data-kind="primary">foo</span>

$("#test").attr("title");
$("#test").attr("data-kind");
$("#test").data("kind");
$("#test").data("value", "bar");
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.