0
# Advanced Features
1
2
Promise/Deferred pattern, callback management, extended selectors, and method chaining for complex applications. These features provide advanced functionality for sophisticated web applications.
3
4
## Capabilities
5
6
### Promise/Deferred Pattern
7
8
Asynchronous programming with jQuery-compatible promises.
9
10
```javascript { .api }
11
/**
12
* Create a Deferred object for managing asynchronous operations
13
* @param func - Optional function to configure the deferred
14
* @returns Deferred object with promise interface
15
*/
16
$.Deferred(func);
17
18
/**
19
* Wait for multiple promises/deferreds to complete
20
* @param deferreds - Multiple deferred objects or promises
21
* @returns Promise that resolves when all inputs resolve
22
*/
23
$.when(...deferreds);
24
```
25
26
**Deferred Object Methods:**
27
28
```javascript { .api }
29
// Deferred object interface
30
interface Deferred {
31
/** Resolve the deferred with optional arguments */
32
resolve(...args): Deferred;
33
/** Reject the deferred with optional arguments */
34
reject(...args): Deferred;
35
/** Notify progress with optional arguments */
36
notify(...args): Deferred;
37
/** Resolve with specific context */
38
resolveWith(context, args): Deferred;
39
/** Reject with specific context */
40
rejectWith(context, args): Deferred;
41
/** Notify progress with specific context */
42
notifyWith(context, args): Deferred;
43
/** Add success callback */
44
done(callback): Deferred;
45
/** Add failure callback */
46
fail(callback): Deferred;
47
/** Add completion callback (success or failure) */
48
always(callback): Deferred;
49
/** Add progress callback */
50
progress(callback): Deferred;
51
/** Add success, failure, and progress callbacks */
52
then(doneCallback, failCallback, progressCallback): Promise;
53
/** Get promise object (read-only interface) */
54
promise(obj): Promise;
55
/** Get current state ('pending', 'resolved', 'rejected') */
56
state(): string;
57
}
58
```
59
60
**Usage Examples:**
61
62
```javascript
63
// Basic deferred usage
64
function asyncOperation() {
65
const deferred = $.Deferred();
66
67
setTimeout(() => {
68
if (Math.random() > 0.5) {
69
deferred.resolve('Success!', {data: 'result'});
70
} else {
71
deferred.reject('Failed!', {error: 'timeout'});
72
}
73
}, 1000);
74
75
return deferred.promise();
76
}
77
78
// Using the promise
79
asyncOperation()
80
.done((message, data) => {
81
console.log('Success:', message, data);
82
})
83
.fail((error, details) => {
84
console.log('Error:', error, details);
85
})
86
.always(() => {
87
console.log('Operation completed');
88
});
89
90
// Multiple operations with $.when
91
const promise1 = asyncOperation();
92
const promise2 = $.get('/api/data');
93
const promise3 = $.getJSON('/api/config');
94
95
$.when(promise1, promise2, promise3)
96
.done((result1, result2, result3) => {
97
console.log('All operations successful');
98
})
99
.fail(() => {
100
console.log('One or more operations failed');
101
});
102
```
103
104
### Callback Management
105
106
Manage lists of callbacks with configurable behavior.
107
108
```javascript { .api }
109
/**
110
* Create a callback list with configurable options
111
* @param options - Configuration string (space-separated flags)
112
* @returns Callbacks object for managing callback lists
113
*/
114
$.Callbacks(options);
115
116
// Options:
117
// 'once' - Callbacks can only be fired once
118
// 'memory' - Remember previous fire arguments for new callbacks
119
// 'unique' - Prevent duplicate callbacks
120
// 'stopOnFalse' - Stop firing when a callback returns false
121
```
122
123
**Callbacks Object Methods:**
124
125
```javascript { .api }
126
interface Callbacks {
127
/** Add callback(s) to the list */
128
add(...callbacks): Callbacks;
129
/** Remove callback(s) from the list */
130
remove(...callbacks): Callbacks;
131
/** Fire all callbacks with given arguments */
132
fire(...args): Callbacks;
133
/** Check if callbacks have been fired */
134
fired(): boolean;
135
/** Empty the callback list */
136
empty(): Callbacks;
137
/** Disable the callback list */
138
disable(): Callbacks;
139
/** Check if callbacks are disabled */
140
disabled(): boolean;
141
/** Lock the callback list */
142
lock(): Callbacks;
143
/** Check if callbacks are locked */
144
locked(): boolean;
145
}
146
```
147
148
**Usage Examples:**
149
150
```javascript
151
// Basic callback list
152
const callbacks = $.Callbacks();
153
154
function callback1(data) {
155
console.log('Callback 1:', data);
156
}
157
158
function callback2(data) {
159
console.log('Callback 2:', data);
160
}
161
162
callbacks.add(callback1, callback2);
163
callbacks.fire('Hello World'); // Both callbacks execute
164
165
// Callback list with options
166
const uniqueCallbacks = $.Callbacks('unique memory');
167
uniqueCallbacks.add(callback1);
168
uniqueCallbacks.add(callback1); // Won't be added again due to 'unique'
169
uniqueCallbacks.fire('First call');
170
171
// New callbacks added later will receive 'memory' of previous fire
172
uniqueCallbacks.add(callback2); // Immediately fires with 'First call'
173
174
// One-time callbacks
175
const onceCallbacks = $.Callbacks('once');
176
onceCallbacks.add(callback1);
177
onceCallbacks.fire('Only once'); // Works
178
onceCallbacks.fire('Ignored'); // Ignored due to 'once'
179
180
// Stop on false
181
const stoppableCallbacks = $.Callbacks('stopOnFalse');
182
stoppableCallbacks.add(
183
() => { console.log('First'); return true; },
184
() => { console.log('Second'); return false; },
185
() => { console.log('Third - will not execute'); }
186
);
187
stoppableCallbacks.fire(); // Only first two execute
188
```
189
190
### Extended Selectors
191
192
jQuery-compatible pseudo-selectors for advanced element selection.
193
194
```javascript { .api }
195
// Extended pseudo-selectors available:
196
// :visible - Elements that are visible
197
// :hidden - Elements that are hidden
198
// :selected - Selected option elements
199
// :checked - Checked input elements (checkbox, radio)
200
// :parent - Elements that have child nodes
201
// :first - First element in the set
202
// :last - Last element in the set
203
// :eq(n) - Element at index n
204
// :contains(text) - Elements containing specific text
205
// :has(selector) - Elements containing descendants matching selector
206
```
207
208
**Usage Examples:**
209
210
```javascript
211
// Visibility selectors
212
$('.element:visible').addClass('currently-shown');
213
$('.element:hidden').removeClass('unnecessary-class');
214
215
// Form element selectors
216
$('input:checked').each(function() {
217
console.log('Checked value:', $(this).val());
218
});
219
220
$('option:selected').each(function() {
221
console.log('Selected option:', $(this).text());
222
});
223
224
// Content selectors
225
$('div:parent').addClass('has-content'); // Divs with child elements
226
$('p:contains("important")').addClass('highlight');
227
228
// Position selectors
229
$('.item:first').addClass('first-item');
230
$('.item:last').addClass('last-item');
231
$('.item:eq(2)').addClass('third-item'); // Zero-indexed
232
233
// Hierarchical selectors
234
$('.container:has(.warning)').addClass('contains-warning');
235
$('div:has(> .direct-child)').addClass('has-direct-child');
236
237
// Complex combinations
238
$('.list-item:visible:contains("active"):has(.icon)').addClass('special');
239
```
240
241
### Method Chaining Stack
242
243
Advanced method chaining with ability to traverse back through previous selections.
244
245
```javascript { .api }
246
/**
247
* End current filtering operation and return to previous set
248
* @returns Previous collection in the chain
249
*/
250
$.fn.end();
251
252
/**
253
* Add previous set to current set
254
* @returns Combined collection (current + previous)
255
*/
256
$.fn.andSelf();
257
```
258
259
**Usage Examples:**
260
261
```javascript
262
// Basic chaining with end()
263
$('.container')
264
.find('.item')
265
.addClass('found-item')
266
.filter('.active')
267
.addClass('active-item')
268
.end() // Back to all .item elements
269
.addClass('processed')
270
.end() // Back to .container elements
271
.addClass('container-processed');
272
273
// Using andSelf() to combine sets
274
$('.parent')
275
.children('.child')
276
.andSelf() // Now includes both .parent and .child elements
277
.addClass('combined-class');
278
279
// Complex chaining example
280
$('#main')
281
.find('.section')
282
.addClass('section-found')
283
.filter(':visible')
284
.addClass('visible-section')
285
.find('.content')
286
.addClass('content-processed')
287
.end() // Back to visible sections
288
.end() // Back to all sections
289
.siblings('.sidebar')
290
.addClass('sidebar-processed')
291
.end() // Back to sections
292
.end() // Back to #main
293
.addClass('main-processed');
294
295
// Practical example: form validation with chaining
296
$('#myForm')
297
.find('input[required]')
298
.addClass('required-field')
299
.filter(':invalid')
300
.addClass('error')
301
.siblings('.error-message')
302
.show()
303
.end() // Back to invalid inputs
304
.end() // Back to all required inputs
305
.filter(':valid')
306
.removeClass('error')
307
.siblings('.error-message')
308
.hide()
309
.end() // Back to valid inputs
310
.end() // Back to all required inputs
311
.end() // Back to form
312
.addClass('validated');
313
```
314
315
### Stack Tracking
316
317
Internal stack management for method chaining.
318
319
```javascript
320
// Methods that create new stacks and support end():
321
// - filter(), add(), not(), eq(), first(), last()
322
// - find(), closest(), parents(), parent(), children(), siblings()
323
324
// Each creates a new collection with prevObject reference
325
function demonstrateStack() {
326
const $original = $('.container');
327
const $filtered = $original.filter('.active');
328
const $children = $filtered.children('.item');
329
330
console.log('Original length:', $original.length);
331
console.log('Filtered length:', $filtered.length);
332
console.log('Children length:', $children.length);
333
334
// prevObject allows traversing back
335
console.log('Children -> filtered:', $children.end().length);
336
console.log('Filtered -> original:', $children.end().end().length);
337
}
338
```
339
340
### Compatibility Polyfills
341
342
Legacy browser compatibility enhancements.
343
344
```javascript { .api }
345
// iOS 3.x compatibility polyfills:
346
// String.prototype.trim - String trimming method
347
// Array.prototype.reduce - Array reduce method
348
349
// These are automatically applied when the ios3 module is included
350
```
351
352
**Usage Examples:**
353
354
```javascript
355
// These methods work even on iOS 3.x when ios3 module is included
356
const text = ' hello world '.trim(); // Works on iOS 3.2+
357
const sum = [1, 2, 3, 4].reduce((a, b) => a + b, 0); // Works on iOS 3.x
358
359
// Check for polyfill presence
360
if (String.prototype.trim) {
361
console.log('Trim method available');
362
}
363
364
if (Array.prototype.reduce) {
365
console.log('Reduce method available');
366
}
367
```
368
369
### Performance Patterns
370
371
Optimizing advanced feature usage for better performance.
372
373
```javascript
374
// Efficient chaining patterns
375
// Good: minimize DOM queries
376
const $container = $('.container');
377
$container.find('.item').addClass('processed');
378
$container.addClass('container-ready');
379
380
// Less efficient: repeated queries
381
$('.container').find('.item').addClass('processed');
382
$('.container').addClass('container-ready');
383
384
// Promise batching for multiple async operations
385
function batchAsyncOperations(operations) {
386
const promises = operations.map(op => {
387
const deferred = $.Deferred();
388
setTimeout(() => {
389
deferred.resolve(op.result);
390
}, op.delay || 0);
391
return deferred.promise();
392
});
393
394
return $.when.apply($, promises);
395
}
396
397
// Callback list reuse
398
const sharedCallbacks = $.Callbacks('memory unique');
399
sharedCallbacks.add(commonHandler1, commonHandler2);
400
401
// Reuse for multiple events
402
$('.trigger1').on('click', () => sharedCallbacks.fire('trigger1'));
403
$('.trigger2').on('click', () => sharedCallbacks.fire('trigger2'));
404
405
// Selector caching for extended selectors
406
const $visibleItems = $('.item:visible'); // Cache expensive selector
407
$visibleItems.addClass('processed');
408
// Later...
409
$visibleItems.removeClass('processed');
410
```
411
412
### Integration Examples
413
414
Combining advanced features for complex scenarios.
415
416
```javascript
417
// Advanced form handling with multiple features
418
function setupAdvancedForm($form) {
419
const validationCallbacks = $.Callbacks('stopOnFalse memory');
420
const submitDeferred = $.Deferred();
421
422
// Add validation callbacks
423
validationCallbacks.add(
424
() => validateRequired($form),
425
() => validateEmail($form),
426
() => validatePasswords($form)
427
);
428
429
// Form submission with promise
430
$form.on('submit', function(e) {
431
e.preventDefault();
432
433
// Run all validations
434
const isValid = validationCallbacks.fire().fired();
435
436
if (isValid) {
437
// Submit with promise pattern
438
$.ajax({
439
url: $form.attr('action'),
440
method: 'POST',
441
data: $form.serialize()
442
})
443
.done((response) => {
444
submitDeferred.resolve(response);
445
})
446
.fail((error) => {
447
submitDeferred.reject(error);
448
});
449
} else {
450
submitDeferred.reject('Validation failed');
451
}
452
});
453
454
return submitDeferred.promise();
455
}
456
457
// Usage
458
setupAdvancedForm($('#registrationForm'))
459
.done((response) => {
460
showSuccessMessage('Registration successful!');
461
})
462
.fail((error) => {
463
showErrorMessage('Registration failed: ' + error);
464
});
465
```