2015-03-23 4 views
5

मैं आमतौर पर अपनी स्क्रिप्ट में jQuery लाइब्रेरी को शामिल करने से बचता हूं, हालांकि मैं हाल ही में jQuery मूल्य $ .data() की मुख्य कार्यक्षमता के रूप में डेटा जोड़ने के लिए कार्य करने की क्षमता, ऑब्जेक्ट & किसी भी के साथ कार्य करता हूं तत्व।

जो मैंने पढ़ा है, उससे jQuery की $ .data() फ़ंक्शन भी सुरक्षा उपायों में बनाया गया है जो इस तरह के प्रथाओं से जुड़े स्मृति रिसाव को रोकता है, लेकिन उस एकल फ़ंक्शन के लिए संपूर्ण जेक्यू लाइब्रेरी को शामिल करना अधिक है।

क्या किसी को मूल विकल्प के बारे में पता है?

संपादित करें खुद को और स्पष्ट करने के लिए, मैं तत्व विशेषताओं को पुनर्प्राप्त करने के लिए मूल कार्य नहीं ढूंढ रहा हूं। jQuery की $ .data() एपीआई जावास्क्रिप्ट ऑब्जेक्ट्स & jQuery तत्व नोड्स के साथ फ़ंक्शंस को जोड़ने की क्षमता के विस्तार से इस तरह के उपयोग से बहुत दूर है।

यह लेख (http://tutorialzine.com/2010/11/jquery-data-method/) इस प्रयोग पर छू लेती है, लेकिन मैं वर्तमान में इसका उपयोग कर रहा हूँ एक उदाहरण के रूप एक वस्तु के साथ एक GSAP समय एनीमेशन संबद्ध करने के लिए, ताकि मैं पहुँच सकते हैं और के बाहर GSAP समय के .reverse() एनीमेशन समारोह कॉल कर सकते हैं वह कार्य जो इसे बनाया गया है। उदाहरण के लिए:

function doAnimation(){ 
    var element = document.createElement('div'), 
     timeline = new TimelineMax({....GSAP related fns...}), 
     options = { 
      .... 
      timeline: timeline 
     }; 
    $(element).data('options', options); 
} 


function reverseAnimation($element){ 
    var options = $element.data('options'), 
     previouslyCreatedTimeline = options.timeline; 

    previouslyCreatedTimeline.reverse(); 
} 

शायद नहीं स्पष्ट उदाहरण है अगर आप GSAP के एक उपयोगकर्ता नहीं हैं, लेकिन संक्षेप में, $ .data() विधि मुझे एक तत्व के साथ एक जावास्क्रिप्ट वस्तु संबद्ध करने के लिए अनुमति दी है, ताकि मैं अपने मूल दायरे के बाहर किसी फ़ंक्शन में इसकी विधियों तक पहुंच सकते हैं।

+0

संभावित डुप्लिकेट [जावास्क्रिप्ट का उपयोग कर डेटा विशेषता सेट करें] (http://stackoverflow.com/questions/11286661/set-data-attribute-using-javascript) – DrCord

+0

नहीं, डुप्लिकेट नहीं। यद्यपि jquery की डेटा फ़ंक्शन विधि मुख्य रूप से किसी तत्व पर डेटा विशेषताओं के लिए उपयोग की जाती है, लेकिन मैं इसे वास्तविक जावास्क्रिप्ट ऑब्जेक्ट्स – AJeezy9

+0

से संबद्ध करने के लिए इसके उपयोग की बात कर रहा हूं, आप 'document.getElementById ("foo") जैसी कुछ क्यों नहीं कर सकते हैं। बार = {बाज़: फ़ंक्शन() {}} '? –

उत्तर

1

setAttribute विधि का उपयोग करें:

document.getElementById('item1').setAttribute('data', "icon: 'base2.gif', url: 'output.htm', target: 'AccessPage', output: '1'"); 

लेकिन क्या तुम सच में डेटा का उपयोग कर किया जाना चाहिए की तरह, एक पानी का छींटा के साथ और उसके संपत्ति के साथ पीछा किया:

<li ... data-icon="base.gif" ...> 

और जे एस में यह करने के लिए डाटासेट का उपयोग संपत्ति:

document.getElementById('item1').dataset.icon = "base.gif"; 
+0

अपनी प्रतिक्रिया की सराहना करते हैं, लेकिन कृपया एक स्पष्ट स्पष्टीकरण के लिए उपर्युक्त संपादन देखें कि यह सही उत्तर क्यों नहीं है। मैं उस लेख की खोज करूंगा जो इस उपयोग को बेहतर तरीके से समझाता है और मेरे पास समय होने पर उससे लिंक होता है। – AJeezy9

+0

ऐसा लगता है कि आप सुपर मूल जावास्क्रिप्ट में निर्मित कुछ ऐसा करने के लिए कह रहे हैं ... किसी ऑब्जेक्ट में अधिक डेटा जोड़ना ... शायद आपको स्पष्ट करना चाहिए कि "सहयोगी डेटा, मुख्य मूल्य जोड़े के रूप में , वस्तुओं और यहां तक ​​कि कार्यों, किसी भी तत्व के साथ। " – DrCord

+0

मैं भ्रम को समझता हूं। ऊपर, मैंने एक लेख से जुड़ा हुआ है और बेहतर तरीके से समझने में आपकी सहायता के लिए अपना स्वयं का उदाहरण उपयोग केस प्रदान किया है। मेरी इच्छा है कि भ्रम से बचने के लिए सवाल अधिक स्पष्ट रूप से लिखा जा सकता था, लेकिन बेहतर तरीके से नहीं सोच सका। – AJeezy9

2

निम्नलिखित सामान्य डेटा फ़ंक्शन देखें। ऑब्जेक्ट को दिए गए कुंजी के साथ मेटाडेटा सेट करने के लिए किसी ऑब्जेक्ट को दिए गए किसी दिए गए कुंजी के साथ मेटाडेटा प्राप्त करने के लिए $.data(obj, key) किसी ऑब्जेक्ट को जिम्मेदार सभी मेटाडेटा प्राप्त करने के लिए $.data(obj) का उपयोग करें, और $.data(obj, key, val)। देशी ऑब्जेक्ट विशेषताओं के टकराव के साथ समस्या हो सकती है जैसे 'toString' या 'hasOwnProperty' की कुंजी के साथ कुछ सेट करना।

$.data(document.body); // Returns {} because no data has been set for this object 
$.data(document.body, 'lastUpdate', new Date());//Sets 'lastUpdate' of obj to current time 
$.data(document.body, 'lastUpdate'); // Gets previously set time 
$.data(document.body); // Gets object of all data, including 'lastUpdate' time 
$.data(document.body, 'nonexistant'); // Returns undefined because property was never set 
$.data(); // Returns all metadata 
+0

वह समाधान स्मृति को रिसाव करने लगता है। – Bergi

+0

यह सबसे अच्छा समाधान की तरह लगता है। आप कैसे जानते हैं कि इसमें स्मृति रिसाव है? इस पर मेमोरी रिसाव को ठीक करना सबसे अच्छा समाधान आईएमओ होगा। – DrCord

+0

नाम टकराव से बचने के लिए, '_data' –

1

सरल कुंजी-मान भंडारण के लिए, .dataset, जो तत्व की data-* विशेषताओं को दर्शाता है का उपयोग करें:

window.$ = { 
    data: function(obj, key, val) { 
     if(!obj) { 
      return this._data; 
     } else if(!key) { 
      if(!(obj in this._data)) { 
       return {}; 
      } 
      return this._data[obj]; 
     } else if(arguments.length < 3) { 
      if(!(obj in this._data)) { 
       return undefined; 
      } 
      return this._data[obj][key]; 
     } else { 
      if(!(obj in this._data)) { 
       this._data[obj] = {}; 
      } 
      this._data[obj][key] = val; 
     } 
    }, 
    _data: {} 
}; 

यहाँ उसके उपयोग के तरीके का एक उदाहरण है। यह स्ट्रिंग मानों तक सीमित है, इसलिए आपको समग्र मानों को क्रमबद्ध करने की आवश्यकता होगी (उदाहरण के लिए JSON का उपयोग करना)।

वस्तुओं और कार्यों के संदर्भों को संग्रहीत करने के लिए, मैं WeakMap का उपयोग करने की अनुशंसा करता हूं। यह किसी भी स्मृति रिसाव से बचने के लिए ख्याल रखेगा। ब्राउज़र में जो इसका समर्थन नहीं करते हैं, उन्हें HTML तत्व पर सीधे संपत्ति के रूप में संग्रहित करें, लेकिन टक्कर मुक्त संपत्ति नामों का चयन करने के लिए सावधानी बरतें।

2

आप किसी भी डोम तत्व पर कुछ भी स्टोर कर सकता है:

// store data: 
document.body.data = {a:1, b:2}; 

// retrieve data: 
console.log(document.body.data); 

मैं यहाँ data शब्द का इस्तेमाल एक कस्टम डोम संपत्ति के रूप में है, लेकिन यह किसी भी शब्द हो जो पहले से उपयोग में हो सकता है।


jQuery क्योंकि यह मेमोरी लीक हो सकती है, तत्व स्वयं पर चीजों की दुकान नहीं है, लेकिन जब से तुम एक बहुत ही विशेष कार्य के लिए इस की जरूरत है, तो यह काम करेगा। बस यह सुनिश्चित करने के पहले कि आप इसे याद करने से पहले मेमोरी लीक कैसे काम करते हैं, सुनिश्चित करें।

अन्य उत्तरों ने data HTML विशेषता का उल्लेख किया। इसका jQuery data से कोई लेना देना नहीं है। बिल्कुल कुछ नहीं, और यह भी आपको अपने डेटा को पार्स और स्ट्रिंग करने की आवश्यकता है (यदि यह पहले से ही एक स्ट्रिंग नहीं है)।

+0

Google को संदर्भित न होने की उम्मीद में, मेमोरी लीक को समझने के बारे में आप किसी भी गुणवत्ता संसाधन से लिंक कर सकते हैं? क्योंकि मैं खिड़की पर परिवर्तनीय डेटा संग्रहीत करने के कई तरीकों के बारे में सोच सकता हूं, लेकिन इस प्रश्न पूछने के लिए मेमोरी लीक प्राथमिक कारण है। मुझे लगता है कि यह उन विषयों में से एक है जो मुझे पता है कि प्रदर्शन के लिए अविश्वसनीय रूप से महत्वपूर्ण है, लेकिन यह भी कुछ हद तक मिथक है कि यह कैसे/कब/क्यों होता है। – AJeezy9

+0

@ AJeezy9 - ठीक है, यदि आप कोई तत्व हटाते हैं, और वह तत्व ऊपर की तकनीक का उपयोग करता है, और उस हटाए गए तत्व पर डेटा किसी अन्य DOM तत्व को इंगित करता है, तो इससे स्मृति रिसाव हो सकता है। – vsync

1

मैंने वीकैप और मानचित्र के चारों ओर एक रैपर लिखा है, जो नौकरी करना चाहिए। वीकैप के बारे में अच्छी बात यह है कि एलिमेंट हटा दिए जाने के बाद मूल्य को कचरा इकट्ठा किया जाता है। यह स्मृति रिसाव से बचना चाहिए।

/** A storage solution aimed at replacing jQuerys data function. 
* Implementation Note: Elements are stored in a (WeakMap)[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap]. 
* This makes sure the data is garbage collected when the node is removed. 
*/ 
window.dataStorage = { 
    _storage: new WeakMap(), 
    put: function (element, key, obj) { 
     if (!this._storage.has(key)) { 
      this._storage.set(element, new Map()); 
     } 
     this._storage.get(element).set(key, obj); 
    }, 
    get: function (element, key) { 
     return this._storage.get(element).get(key); 
    }, 
    has: function (element, key) { 
     return this._storage.get(element).has(key); 
    }, 
    remove: function (element, key) { 
     var ret = this._storage.get(element).delete(key); 
     if (!this._storage.get(key).size === 0) { 
      this._storage.delete(element); 
     } 
     return ret; 
    } 
} 

इस तरह यह प्रयोग करें:

var myElement = document.getElementById("myId"); 
dataStorage.put(myElement, "myKey", "myValue"); 

यह $ .data() की तुलना में बहुत तेजी से, लेकिन अभी भी एक तत्व पर एक संपत्ति के रूप में सूचना के संचय की तुलना में थोड़ा धीमी है।

संबंधित मुद्दे