0
# Data Management
1
2
Data attribute handling and internal data storage system for associating arbitrary data with DOM elements. Provides both HTML5 data attributes and internal storage.
3
4
## Capabilities
5
6
### Data Attributes
7
8
Work with HTML5 data-* attributes with automatic type conversion.
9
10
```javascript { .api }
11
/**
12
* Get or set data attributes on elements
13
* @param name - Data attribute name (without 'data-' prefix)
14
* @param value - Value to set (if setting)
15
* @returns Data value (if getting) or collection (if setting)
16
*/
17
$.fn.data(name, value);
18
19
/**
20
* Remove data attributes from elements
21
* @param names - Space-separated data attribute names to remove
22
* @returns Original collection
23
*/
24
$.fn.removeData(names);
25
```
26
27
**Usage Examples:**
28
29
```javascript
30
// Set data attributes
31
$('.item').data('id', 123);
32
$('.item').data('config', {theme: 'dark', size: 'large'});
33
34
// Get data attributes
35
const itemId = $('.item').data('id'); // Returns 123 (number)
36
const config = $('.item').data('config'); // Returns object
37
38
// Data attributes in HTML
39
// <div class="item" data-id="456" data-active="true" data-tags='["tag1", "tag2"]'></div>
40
41
const id = $('.item').data('id'); // 456 (number)
42
const active = $('.item').data('active'); // true (boolean)
43
const tags = $('.item').data('tags'); // ['tag1', 'tag2'] (array)
44
45
// Remove data
46
$('.item').removeData('id config');
47
```
48
49
### Internal Data Storage
50
51
Store arbitrary data internally without modifying DOM attributes.
52
53
```javascript { .api }
54
/**
55
* Store data associated with DOM elements
56
* @param elem - DOM element
57
* @param name - Data property name
58
* @param value - Data value to store
59
* @returns Stored value
60
*/
61
$.data(elem, name, value);
62
63
/**
64
* Check if element has stored data
65
* @param elem - DOM element to check
66
* @returns True if element has data
67
*/
68
$.hasData(elem);
69
70
/**
71
* Unique property name for data storage
72
*/
73
$.expando; // Internal property name used for data storage
74
```
75
76
**Usage Examples:**
77
78
```javascript
79
// Store internal data
80
const element = document.getElementById('myElement');
81
$.data(element, 'widget', new MyWidget());
82
$.data(element, 'initialized', true);
83
84
// Retrieve internal data
85
const widget = $.data(element, 'widget');
86
const isInitialized = $.data(element, 'initialized');
87
88
// Check for data
89
if ($.hasData(element)) {
90
console.log('Element has associated data');
91
}
92
93
// Using with Zepto collections
94
$('.widget').each(function() {
95
const widget = $.data(this, 'instance');
96
if (widget) {
97
widget.update();
98
}
99
});
100
```
101
102
### Data Type Conversion
103
104
Automatic conversion of data attribute values to appropriate JavaScript types.
105
106
```javascript
107
// HTML data attributes with automatic conversion:
108
// data-number="42" → 42 (number)
109
// data-float="3.14" → 3.14 (number)
110
// data-boolean="true" → true (boolean)
111
// data-boolean="false" → false (boolean)
112
// data-null="null" → null
113
// data-json='{"key":"value"}' → {key: 'value'} (object)
114
// data-array='[1,2,3]' → [1, 2, 3] (array)
115
// data-string="hello" → "hello" (string)
116
117
// Examples:
118
// <div data-count="5" data-active="true" data-config='{"theme":"dark"}'></div>
119
120
const count = $('.item').data('count'); // 5 (number)
121
const active = $('.item').data('active'); // true (boolean)
122
const config = $('.item').data('config'); // {theme: 'dark'} (object)
123
```
124
125
### Widget/Plugin Data Patterns
126
127
Common patterns for storing plugin and widget data.
128
129
```javascript
130
// Plugin initialization pattern
131
$.fn.myPlugin = function(options) {
132
return this.each(function() {
133
const $this = $(this);
134
let instance = $this.data('myPlugin');
135
136
if (!instance) {
137
instance = new MyPlugin(this, options);
138
$this.data('myPlugin', instance);
139
}
140
141
return instance;
142
});
143
};
144
145
// Widget state management
146
function initializeWidget($element) {
147
const config = $element.data('config') || {};
148
const widget = {
149
element: $element[0],
150
options: $.extend({}, defaultOptions, config),
151
state: 'initialized'
152
};
153
154
$element.data('widget-instance', widget);
155
return widget;
156
}
157
158
// Data-driven configuration
159
$('.configurable').each(function() {
160
const $this = $(this);
161
const config = {
162
theme: $this.data('theme') || 'default',
163
size: $this.data('size') || 'medium',
164
enabled: $this.data('enabled') !== false
165
};
166
167
initializeComponent($this, config);
168
});
169
```
170
171
### Memory Management
172
173
Automatic cleanup and memory management for stored data.
174
175
```javascript
176
// Data is automatically cleaned up when elements are removed
177
$('.widget').remove(); // Associated data is cleaned up automatically
178
179
// Manual cleanup
180
$('.temporary').removeData(); // Remove all data
181
$('.cache').removeData('cache results'); // Remove specific data
182
183
// Check for memory leaks
184
function checkDataLeaks() {
185
let elementCount = 0;
186
let dataCount = 0;
187
188
$('*').each(function() {
189
elementCount++;
190
if ($.hasData(this)) {
191
dataCount++;
192
}
193
});
194
195
console.log(`Elements: ${elementCount}, With data: ${dataCount}`);
196
}
197
198
// Enhanced remove method cleans up data
199
$.fn.remove = function() {
200
return this.each(function() {
201
// Clean up data before removing
202
$(this).removeData();
203
$(this).find('*').removeData();
204
205
// Remove from DOM
206
if (this.parentNode) {
207
this.parentNode.removeChild(this);
208
}
209
});
210
};
211
```
212
213
### Event Data Integration
214
215
Combining data storage with event handling.
216
217
```javascript
218
// Store event handlers with data
219
$('.interactive').each(function(index) {
220
const $this = $(this);
221
222
// Store element-specific data
223
$this.data('index', index);
224
$this.data('clickCount', 0);
225
226
// Event handler using stored data
227
$this.on('click', function() {
228
const index = $this.data('index');
229
let clickCount = $this.data('clickCount');
230
231
clickCount++;
232
$this.data('clickCount', clickCount);
233
234
console.log(`Element ${index} clicked ${clickCount} times`);
235
});
236
});
237
238
// Pass data to event handlers
239
$('.button').on('click', {action: 'save', id: 123}, function(e) {
240
console.log('Action:', e.data.action);
241
console.log('ID:', e.data.id);
242
});
243
```
244
245
### Cache Management
246
247
Using data storage for caching and performance optimization.
248
249
```javascript
250
// Cache expensive computations
251
function getExpensiveData($element) {
252
let cached = $element.data('expensive-cache');
253
254
if (!cached) {
255
// Perform expensive computation
256
cached = performExpensiveComputation();
257
$element.data('expensive-cache', cached);
258
}
259
260
return cached;
261
}
262
263
// Cache with expiration
264
function getCachedData($element, key, computeFn, ttl = 60000) {
265
const now = Date.now();
266
const cached = $element.data(key);
267
268
if (cached && cached.timestamp && (now - cached.timestamp) < ttl) {
269
return cached.data;
270
}
271
272
const fresh = computeFn();
273
$element.data(key, {
274
data: fresh,
275
timestamp: now
276
});
277
278
return fresh;
279
}
280
281
// Usage
282
const data = getCachedData($('.expensive'), 'api-data', () => {
283
return $.getJSON('/api/data');
284
}, 300000); // 5 minute cache
285
```
286
287
### Best Practices
288
289
Recommendations for effective data management.
290
291
```javascript
292
// Use consistent naming conventions
293
$('.item').data('item-id', 123); // kebab-case for HTML attributes
294
$('.item').data('itemId', 123); // camelCase for JavaScript
295
296
// Namespace data to avoid conflicts
297
$('.widget').data('myPlugin.config', config);
298
$('.widget').data('myPlugin.state', state);
299
300
// Store references, not copies
301
const largeObject = {/* large data */};
302
$('.item').data('reference', largeObject); // Store reference
303
// Not: $('.item').data('copy', $.extend({}, largeObject));
304
305
// Clean up data when destroying components
306
function destroyWidget($element) {
307
const widget = $element.data('widget-instance');
308
if (widget) {
309
widget.cleanup();
310
$element.removeData('widget-instance');
311
}
312
}
313
314
// Use data for configuration, not large datasets
315
// Good: $('.chart').data('config', {type: 'line', color: 'blue'});
316
// Bad: $('.chart').data('dataset', hugeArrayOfData);
317
```