CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-zepto

Zepto is a minimalist JavaScript library for modern browsers with a largely jQuery-compatible API

Overview
Eval results
Files

advanced-features.mddocs/

Advanced Features

Promise/Deferred pattern, callback management, extended selectors, and method chaining for complex applications. These features provide advanced functionality for sophisticated web applications.

Capabilities

Promise/Deferred Pattern

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');
  });

Callback Management

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 false

Callbacks 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 execute

Extended Selectors

jQuery-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 selector

Usage 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');

Method Chaining Stack

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');

Stack Tracking

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);
}

Compatibility Polyfills

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 included

Usage 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');
}

Performance Patterns

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');

Integration Examples

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);
  });

Install with Tessl CLI

npx tessl i tessl/npm-zepto

docs

advanced-features.md

ajax.md

animation.md

browser-detection.md

callback-management.md

core-dom.md

css-styling.md

data-management.md

enhanced-selectors.md

events.md

forms.md

index.md

mobile-touch.md

stack-operations.md

tile.json