jQuery .data () काम नहीं करता है, लेकिन .attr () करता है


107

इस पर अधिक विशिष्ट न होने के लिए मुझे क्षमा करें। मेरे पास ऐसा एक अजीब बग है। डॉक्स लोड होने के बाद, मैं कुछ तत्वों को देखता हूं जो मूल रूप से हैं data-itemname="", और मैंने उन मूल्यों का उपयोग करके सेट किया है .attr("data-itemname", "someValue")

समस्या: जब मैं बाद में उन तत्वों के माध्यम से लूप करता हूं, अगर मैं करता हूं, तो elem.data().itemnameमुझे मिलता है "", लेकिन अगर मैं करता elem.attr("data-itemname")हूं, तो मुझे मिलता है "someValue"। यह ऐसा है जैसे कि jQuery का .data()गेटटर केवल उन तत्वों को प्राप्त करता है जो शुरू में कुछ मान सम्‍मिलित करने के लिए सेट किए गए हैं, लेकिन यदि वे मूल रूप से खाली हैं, और बाद में सेट हैं, तो .data()बाद में मान नहीं मिलता है।

मैं इस बग को फिर से बनाने की कोशिश कर रहा हूं, लेकिन नहीं कर पाया हूं।

संपादित करें

मैंने बग को फिर से बनाया है! http://jsbin.com/ihuhep/edit#javascript,html,live

इसके अलावा, ऊपर लिंक से स्निपेट्स ...

जे एस:

var theaters = [
    { name: "theater A", theaterId: 5 },
    { name: "theater B", theaterId: 17 }
];

$("#theaters").html(
    $("#theaterTmpl").render(theaters)
);

// DOES NOT WORK - .data("name", "val") does NOT set the val
var theaterA = $("[data-theaterid='5']");
theaterA.find(".someLink").data("tofilllater", "theater5link"); // this does NOT set data-tofilllater
$(".someLink[data-tofilllater='theater5link']").html("changed link text"); // never gets changed

// WORKS - .attr("data-name", "val") DOES set val
var theaterB = $("[data-theaterid='17']");
theaterB.find(".someLink").attr("data-tofilllater", "theater17link"); // this does set data-tofilllater
$(".someLink[data-tofilllater='theater17link']").html("changed link text");

HTML:

<body>
    <div id="theaters"></div>
</body>

<script id="theaterTmpl" type="text/x-jquery-tmpl">
    <div class="theater" data-theaterid="{{=theaterId}}">
        <h2>{{=name}}</h2>
        <a href="#" class="someLink" data-tofilllater="">need to change this text</a>
    </div>
</script>

4
बग को
दोबारा

1
है elem.data("itemname")ना elem.data().itemname?
होगन

जबकि elem.data ()। आइटम नाम आपको वह मान पढ़ने देगा जो आपको मान सेट करने नहीं देता है। (इस प्रकार elem.data().itemname = somevalue;अंतर्निहित डेटा में बदलाव नहीं होता है।)
होगन

@ विटामिन - मैंने बग को फिर से बनाया है, कृपया संपादित संस्करण देखें।
इवान डेविस

जवाबों:


210

जब साथ काम कर रहा कुछ दिन पहले एक ऐसी ही "बग" में भाग .data()और .attr('data-name')एचटीएमएल 5 डेटा विशेषताओं के लिए।

आपके द्वारा वर्णित व्यवहार बग नहीं है, लेकिन डिज़ाइन द्वारा है।

.data()कॉल खास है - न केवल यह एचटीएमएल 5 डेटा पुनः प्राप्त है कि यह गुण भी मूल्यांकन / गुण पार्स करने के लिए प्रयास करता है। तो साथ की तरह एक विशेषता data-myjson='{"hello":"world"}'जब के माध्यम से लिया गया .data()एक वापस आ जाएगी Objectके माध्यम से, जबकि पुनर्प्राप्ति .attr()एक स्ट्रिंग वापस आ जाएगी। Jsfiddle उदाहरण देखें।

चूंकि .data()अतिरिक्त प्रसंस्करण jQuery विशेषता मूल्यांकन के परिणामों को संग्रहीत करता है $.cache- आखिरकार, एक बार जब एक डेटा विशेषता का मूल्यांकन किया जाता है तो यह हर .data()कॉल पर पुनर्मूल्यांकन करने के लिए बेकार होगा - विशेष रूप से चूंकि डेटा चर में जटिल JSON स्ट्रिंग्स हो सकते हैं।

मैंने वह सब कहा जो निम्नलिखित कहना है: किसी भी परिवर्तन के माध्यम से एक विशेषता प्राप्त करने के बाद .data()किए गए कॉल के .attr('data-myvar', '')बाद नहीं देखा जाएगा .data() इसे jsfiddle पर टेस्ट करें।

इस समस्या से बचने के लिए इंटरमिक्स .dataऔर .attr()कॉल न करें। एक या दूसरे का उपयोग करें।


इसे उत्तर के रूप में चिह्नित करना। कृपया इस परीक्षण को .data () बनाम .attr () के साथ सभी संभावित परिदृश्यों के लिए देखें, जिसमें प्रत्येक का उपयोग करके प्राप्त करना और सेट करना शामिल है, और उनके सेट होने के बाद चयनकर्ताओं की लंबाई को आउटपुट करना
इयान डेविस

9
कम से कम यह स्पष्ट रूप से गैर-सहज व्यवहार की व्याख्या करता है ... हालांकि यह कुछ छोटे सिरदर्द पैदा कर सकता है जब कोई 3 पार्टी पुस्तकालयों का उपयोग कर रहा है, उनमें से कुछ केवल डेटा () का उपयोग कर रहे हैं, और अन्य वास्तविक विशेषता को बदल रहे हैं।
हैरोल्डो_कॉक

1
@leepowers, ".ata () (डेटा-मायवर ',' ') द्वारा किए गए किसी भी परिवर्तन के माध्यम से एक विशेषता प्राप्त करने के बाद () कॉल के बाद नहीं देखा जाएगा। $ .cache), तो यह अच्छा नहीं लगता है! कैश पर आँख बंद करके भरोसा करने के बजाय, बाद में .data () कॉल कुछ बुनियादी जाँचें कर सकती हैं (जैसे कि क्या अभी खाली हुई या स्ट्रिंग की लंबाई बदल गई है (वर्तमान मूल्य के साथ कैश मिलान करना)
मिन्हाजुल

1
यह ध्यान दिया जाना चाहिए कि डेटा ('आईडी', वैल) सेट करने की कोशिश करना भी विफल हो जाता है यदि मूल्य पहले प्राप्त नहीं किया गया था ... डेटा के महान डिजाइन () जेकरी द्वारा फ़ंक्शन।
andreszs

3
तो, यह डेटा () कैश है जो मुझे घंटों तक रोक रहा है। कोई आश्चर्य नहीं कि मैं चाहे कितना भी इसके मूल्य को बदल दूं, यह अभी भी उसी मूल्य को लौटाता है। इसके लिए धन्यवाद।
लिननेल इमैनुएल नेरी

17

यह एक गलतफहमी का परिणाम है: विशेषताओं के dataलिए एक सहायक नहीं हैdata-* । यह उससे कम और अधिक है।

dataतत्व पर jQuery के डेटा कैश के लिए एक सहायक है। यदि कोई मौजूद हो, तो उस कैश को विशेषताओं से आरंभ किया जाता हैdata-* , लेकिन dataकभी भी विशेषताओं को नहीं लिखा जाता है, और न ही विशेषताओं को बदलने पर डेटा कैश को प्रारंभिक रूप से बदलता है:

const div = $("[data-example]");
console.log('div.data("example"):', div.data("example"));
console.log('div.attr("data-example"):', div.attr("data-example"));
console.log('Using div.data("example", "updated")');
div.data("example", "updated");
console.log('div.data("example"):', div.data("example"));
console.log('div.attr("data-example"):', div.attr("data-example"));
<div data-example="initial value"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

dataयह भी पता चलता है कि यह विभिन्न तरीकों से क्या पाता है, डेटा प्रकारों पर अनुमान लगाता है, एक संख्या के data("answer")साथ data-answer="42"एक तत्व पर बना , न कि एक स्ट्रिंग, या यहां तक ​​कि JSON के रूप में देखने पर JSON के रूप में चीजों को पार्स करना:

console.log(typeof $("[data-answer]").data("answer"));
console.log(typeof $("[data-json]").data("json"));
console.log(typeof $("[data-str]").data("str"));
<div data-answer="42"></div>
<div data-json='{"answer":42}'></div>
<div data-str="example"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

यदि आप विशेषताओं का उपयोग करना चाहते हैं (दोनों पढ़ना और उन्हें सेट करना), का उपयोग करें attr, नहीं dataattr है विशेषताओं के लिए एक्सेसर।


6

ऐसा इसलिए है क्योंकि विशेषता का नाम है data-itemname। आप -शॉर्टहैंड obj.attributeनोटेशन में उपयोग नहीं कर सकते (obj.data-itemname को "obj.data minus itemname" के रूप में संक्षिप्त किया जाएगा)।


कौन कहता है? क्या आप लिंक प्रदान कर सकते हैं?
जहरीली

6

.attr("data-itemname", "someValue") DOM को मॉडिफाई करता है।

.data("itemname", "someValue") jQuery कैश को संशोधित करता है।

जावास्क्रिप्ट में निम्नलिखित काम करने के लिए और सीएसएस में इसके अलावा आपको दोनों को सेट करना होगा।

theaterA.find(".someLink").attr("data-itemname", "someValue");
theaterA.find(".someLink").data("itemname", "someValue");

4

आप .data()हर जगह का उपयोग क्यों नहीं करते ?

आप HTML पर डिफ़ॉल्ट मान इनलाइन भी घोषित कर सकते हैं, जो ठीक भी है।

<span data-code="pony">text</span>

तथा

$("span").data("code") == "pony" // true

यदि आप इसे बदलना चाहते हैं तो आप बस करते हैं

$("span").data("code", "not-a-pony");

और इसे पूरी तरह से हटाने के लिए आप आह्वान कर सकते हैं

$("span").removeData("code");

आपको वास्तव में प्रयास करना चाहिए और उपयोग करने से बचना चाहिए .attr("data-*"), मुझे नहीं पता कि आप ऐसा क्यों करना चाहते हैं।


s / का उपयोग करना चाहिए, .attr('data-*', ...)डेटा को दिखाई नहीं देगा.data()
ThiefMaster

लेकिन यह attr () के साथ नहीं कर रहा है जिस तरह से आप इसे jQuery के बिना करना होगा ? (getAttribute
थियो के

यदि आपके पास jQuery का उपयोग नहीं है getAttribute()और setAttribute()- तो दोनों विधियाँ वास्तविक विशेषताओं तक पहुँचेंगी और यह फिर से काम करेगा। या आप बस dataSetआधुनिक ब्राउज़र प्रदान करने वाली संपत्ति का उपयोग करेंगे ।
ThiefMaster

1
उस तरह के तत्वों का चयन न करें। यह बहुत ही अयोग्य है क्योंकि इसे दस्तावेज़ में हर एक तत्व पर चलना होगा । classएक निश्चित वर्ग के साथ तत्वों को प्राप्त करने के लिए ब्राउज़र के मूल कार्य होने के बजाय इसके बजाय का उपयोग करें ।
ThiefMaster

1
लेकिन, "555" डेटा है, इसलिए मुझे डेटा () तर्क का उपयोग करना चाहिए। उस डेटा को क्लास के नाम में रखकर प्रेजेंटेशन के साथ डेटा मिलाया जा रहा है। ऐसा करने का अलग तरीका मुझे लगता है।
इयान डेविस

1

आपको डेटा का उपयोग करके सेट करना होगा .data('itemname', 'someValue');.attr()डेटा विशेषताओं को सेट करने के लिए उपयोग करने से काम नहीं चलेगा: http://jsfiddle.net/ThiefMaster/YHsKx/

हालाँकि, आप मार्कअप में उदाहरण के द्वारा इनलाइन मान प्रदान कर सकते हैं <div data-key="value">


jsfiddle में, आप दोनों सेट करने के बाद काम करते हैं। इसलिए, attr ("data-itemname", "value") करना काम करता है। मैं क्रोम का उपयोग कर रहा हूं।
इयान डेविस

@ इयान उह, नहीं। .data()कॉल विशेषता सेट करता है, जबकि .attr()कॉल कुछ नहीं करता है।
bevacqua

@IanDavis: "set attr" पर क्लिक करें और "get" आपको एक खाली वस्तु देगा। केवल "सेट डेटा" काम करता है।
ThiefMaster 11

@ निको - यह वही है जो मैंने किया था: (1) "सेट एट्र" बटन पर क्लिक करें, फिर (2) "गेट" बटन पर क्लिक करें। यह वही है जो हुआ: इसने मुझे सचेत किया, "{" परीक्षण ":" म्याऊ "}"। इसलिए, .attr () विशेषता सेट करें। अन्यथा, सूचना खाली होती। यदि आप उन सटीक चरणों का पालन करते हैं, तो क्या आपको अलग-अलग परिणाम मिलते हैं? धन्यवाद।
इयान डेविस

1
@ThiefMaster - मेरी प्रदान की कोड में theaterA में, मैं का उपयोग नहीं .attr()सब पर, केवल .data(), और, चयनकर्ता की लंबाई, $(".someLink[data-tofilllater='theater5link']"), शून्य है। इसलिए यह ऐसा है जैसे मुझे उपयोग करना है .attr(): /
इयान डेविस

0

मैं देख सकता हूं कि यह डेटा विशेषता सेटिंग को कैसे एक्सेस करना है, इस पर कुछ विभाजन लाया है।

मैं भी इस समस्या में भाग लेता हूं और मैंने पाया कि यह समस्या केवल डेटा विशेषता नाम स्वरूपण की थी

मेरे अनुभव में, आपको डेटा चर (" डेटा- " के बाद आने वाले चर नाम ) में हाइफ़न का उपयोग करने से बचना चाहिए ।

यह मेरे लिए काम नहीं किया:

[मार्कअप]

<div class="list" id="myElement1" data-item-order="some-value"> .... </div>

[JQuery]

jQuery("#myElement1").data("item-order", "my-new-value");

लेकिन निम्नलिखित ठीक काम किया! :):

(आवश्यकता पड़ने पर मैं एक हाइफ़न के बजाय एक अंडरस्कोर का उपयोग करता हूं)

[मार्कअप]

<div class="list" id="myElement1" data-item_order="some-value"> .... </div>

[JQuery]

jQuery("#myElement1").data("item_order", "my-new-value");

मुझे उम्मीद है यह मदद करेगा। सबको खुश करता है!

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.