Zepto is a minimalist JavaScript library for modern browsers with a largely jQuery-compatible API
Promise/Deferred pattern, callback management, extended selectors, and method chaining for complex applications. These features provide advanced functionality for sophisticated web applications.
Asynchronous programming with jQuery-compatible promises.
/**
* Create a Deferred object for managing asynchronous operations
* @param func - Optional function to configure the deferred
* @returns Deferred object with promise interface
*/
$.Deferred(func);
/**
* Wait for multiple promises/deferreds to complete
* @param deferreds - Multiple deferred objects or promises
* @returns Promise that resolves when all inputs resolve
*/
$.when(...deferreds);Deferred Object Methods:
// Deferred object interface
interface Deferred {
/** Resolve the deferred with optional arguments */
resolve(...args): Deferred;
/** Reject the deferred with optional arguments */
reject(...args): Deferred;
/** Notify progress with optional arguments */
notify(...args): Deferred;
/** Resolve with specific context */
resolveWith(context, args): Deferred;
/** Reject with specific context */
rejectWith(context, args): Deferred;
/** Notify progress with specific context */
notifyWith(context, args): Deferred;
/** Add success callback */
done(callback): Deferred;
/** Add failure callback */
fail(callback): Deferred;
/** Add completion callback (success or failure) */
always(callback): Deferred;
/** Add progress callback */
progress(callback): Deferred;
/** Add success, failure, and progress callbacks */
then(doneCallback, failCallback, progressCallback): Promise;
/** Get promise object (read-only interface) */
promise(obj): Promise;
/** Get current state ('pending', 'resolved', 'rejected') */
state(): string;
}Usage Examples:
// Basic deferred usage
function asyncOperation() {
const deferred = $.Deferred();
setTimeout(() => {
if (Math.random() > 0.5) {
deferred.resolve('Success!', {data: 'result'});
} else {
deferred.reject('Failed!', {error: 'timeout'});
}
}, 1000);
return deferred.promise();
}
// Using the promise
asyncOperation()
.done((message, data) => {
console.log('Success:', message, data);
})
.fail((error, details) => {
console.log('Error:', error, details);
})
.always(() => {
console.log('Operation completed');
});
// Multiple operations with $.when
const promise1 = asyncOperation();
const promise2 = $.get('/api/data');
const promise3 = $.getJSON('/api/config');
$.when(promise1, promise2, promise3)
.done((result1, result2, result3) => {
console.log('All operations successful');
})
.fail(() => {
console.log('One or more operations failed');
});Manage lists of callbacks with configurable behavior.
/**
* Create a callback list with configurable options
* @param options - Configuration string (space-separated flags)
* @returns Callbacks object for managing callback lists
*/
$.Callbacks(options);
// Options:
// 'once' - Callbacks can only be fired once
// 'memory' - Remember previous fire arguments for new callbacks
// 'unique' - Prevent duplicate callbacks
// 'stopOnFalse' - Stop firing when a callback returns falseCallbacks Object Methods:
interface Callbacks {
/** Add callback(s) to the list */
add(...callbacks): Callbacks;
/** Remove callback(s) from the list */
remove(...callbacks): Callbacks;
/** Fire all callbacks with given arguments */
fire(...args): Callbacks;
/** Check if callbacks have been fired */
fired(): boolean;
/** Empty the callback list */
empty(): Callbacks;
/** Disable the callback list */
disable(): Callbacks;
/** Check if callbacks are disabled */
disabled(): boolean;
/** Lock the callback list */
lock(): Callbacks;
/** Check if callbacks are locked */
locked(): boolean;
}Usage Examples:
// Basic callback list
const callbacks = $.Callbacks();
function callback1(data) {
console.log('Callback 1:', data);
}
function callback2(data) {
console.log('Callback 2:', data);
}
callbacks.add(callback1, callback2);
callbacks.fire('Hello World'); // Both callbacks execute
// Callback list with options
const uniqueCallbacks = $.Callbacks('unique memory');
uniqueCallbacks.add(callback1);
uniqueCallbacks.add(callback1); // Won't be added again due to 'unique'
uniqueCallbacks.fire('First call');
// New callbacks added later will receive 'memory' of previous fire
uniqueCallbacks.add(callback2); // Immediately fires with 'First call'
// One-time callbacks
const onceCallbacks = $.Callbacks('once');
onceCallbacks.add(callback1);
onceCallbacks.fire('Only once'); // Works
onceCallbacks.fire('Ignored'); // Ignored due to 'once'
// Stop on false
const stoppableCallbacks = $.Callbacks('stopOnFalse');
stoppableCallbacks.add(
() => { console.log('First'); return true; },
() => { console.log('Second'); return false; },
() => { console.log('Third - will not execute'); }
);
stoppableCallbacks.fire(); // Only first two executejQuery-compatible pseudo-selectors for advanced element selection.
// Extended pseudo-selectors available:
// :visible - Elements that are visible
// :hidden - Elements that are hidden
// :selected - Selected option elements
// :checked - Checked input elements (checkbox, radio)
// :parent - Elements that have child nodes
// :first - First element in the set
// :last - Last element in the set
// :eq(n) - Element at index n
// :contains(text) - Elements containing specific text
// :has(selector) - Elements containing descendants matching selectorUsage Examples:
// Visibility selectors
$('.element:visible').addClass('currently-shown');
$('.element:hidden').removeClass('unnecessary-class');
// Form element selectors
$('input:checked').each(function() {
console.log('Checked value:', $(this).val());
});
$('option:selected').each(function() {
console.log('Selected option:', $(this).text());
});
// Content selectors
$('div:parent').addClass('has-content'); // Divs with child elements
$('p:contains("important")').addClass('highlight');
// Position selectors
$('.item:first').addClass('first-item');
$('.item:last').addClass('last-item');
$('.item:eq(2)').addClass('third-item'); // Zero-indexed
// Hierarchical selectors
$('.container:has(.warning)').addClass('contains-warning');
$('div:has(> .direct-child)').addClass('has-direct-child');
// Complex combinations
$('.list-item:visible:contains("active"):has(.icon)').addClass('special');Advanced method chaining with ability to traverse back through previous selections.
/**
* End current filtering operation and return to previous set
* @returns Previous collection in the chain
*/
$.fn.end();
/**
* Add previous set to current set
* @returns Combined collection (current + previous)
*/
$.fn.andSelf();Usage Examples:
// Basic chaining with end()
$('.container')
.find('.item')
.addClass('found-item')
.filter('.active')
.addClass('active-item')
.end() // Back to all .item elements
.addClass('processed')
.end() // Back to .container elements
.addClass('container-processed');
// Using andSelf() to combine sets
$('.parent')
.children('.child')
.andSelf() // Now includes both .parent and .child elements
.addClass('combined-class');
// Complex chaining example
$('#main')
.find('.section')
.addClass('section-found')
.filter(':visible')
.addClass('visible-section')
.find('.content')
.addClass('content-processed')
.end() // Back to visible sections
.end() // Back to all sections
.siblings('.sidebar')
.addClass('sidebar-processed')
.end() // Back to sections
.end() // Back to #main
.addClass('main-processed');
// Practical example: form validation with chaining
$('#myForm')
.find('input[required]')
.addClass('required-field')
.filter(':invalid')
.addClass('error')
.siblings('.error-message')
.show()
.end() // Back to invalid inputs
.end() // Back to all required inputs
.filter(':valid')
.removeClass('error')
.siblings('.error-message')
.hide()
.end() // Back to valid inputs
.end() // Back to all required inputs
.end() // Back to form
.addClass('validated');Internal stack management for method chaining.
// Methods that create new stacks and support end():
// - filter(), add(), not(), eq(), first(), last()
// - find(), closest(), parents(), parent(), children(), siblings()
// Each creates a new collection with prevObject reference
function demonstrateStack() {
const $original = $('.container');
const $filtered = $original.filter('.active');
const $children = $filtered.children('.item');
console.log('Original length:', $original.length);
console.log('Filtered length:', $filtered.length);
console.log('Children length:', $children.length);
// prevObject allows traversing back
console.log('Children -> filtered:', $children.end().length);
console.log('Filtered -> original:', $children.end().end().length);
}Legacy browser compatibility enhancements.
// iOS 3.x compatibility polyfills:
// String.prototype.trim - String trimming method
// Array.prototype.reduce - Array reduce method
// These are automatically applied when the ios3 module is includedUsage Examples:
// These methods work even on iOS 3.x when ios3 module is included
const text = ' hello world '.trim(); // Works on iOS 3.2+
const sum = [1, 2, 3, 4].reduce((a, b) => a + b, 0); // Works on iOS 3.x
// Check for polyfill presence
if (String.prototype.trim) {
console.log('Trim method available');
}
if (Array.prototype.reduce) {
console.log('Reduce method available');
}Optimizing advanced feature usage for better performance.
// Efficient chaining patterns
// Good: minimize DOM queries
const $container = $('.container');
$container.find('.item').addClass('processed');
$container.addClass('container-ready');
// Less efficient: repeated queries
$('.container').find('.item').addClass('processed');
$('.container').addClass('container-ready');
// Promise batching for multiple async operations
function batchAsyncOperations(operations) {
const promises = operations.map(op => {
const deferred = $.Deferred();
setTimeout(() => {
deferred.resolve(op.result);
}, op.delay || 0);
return deferred.promise();
});
return $.when.apply($, promises);
}
// Callback list reuse
const sharedCallbacks = $.Callbacks('memory unique');
sharedCallbacks.add(commonHandler1, commonHandler2);
// Reuse for multiple events
$('.trigger1').on('click', () => sharedCallbacks.fire('trigger1'));
$('.trigger2').on('click', () => sharedCallbacks.fire('trigger2'));
// Selector caching for extended selectors
const $visibleItems = $('.item:visible'); // Cache expensive selector
$visibleItems.addClass('processed');
// Later...
$visibleItems.removeClass('processed');Combining advanced features for complex scenarios.
// Advanced form handling with multiple features
function setupAdvancedForm($form) {
const validationCallbacks = $.Callbacks('stopOnFalse memory');
const submitDeferred = $.Deferred();
// Add validation callbacks
validationCallbacks.add(
() => validateRequired($form),
() => validateEmail($form),
() => validatePasswords($form)
);
// Form submission with promise
$form.on('submit', function(e) {
e.preventDefault();
// Run all validations
const isValid = validationCallbacks.fire().fired();
if (isValid) {
// Submit with promise pattern
$.ajax({
url: $form.attr('action'),
method: 'POST',
data: $form.serialize()
})
.done((response) => {
submitDeferred.resolve(response);
})
.fail((error) => {
submitDeferred.reject(error);
});
} else {
submitDeferred.reject('Validation failed');
}
});
return submitDeferred.promise();
}
// Usage
setupAdvancedForm($('#registrationForm'))
.done((response) => {
showSuccessMessage('Registration successful!');
})
.fail((error) => {
showErrorMessage('Registration failed: ' + error);
});