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

callback-management.mddocs/

Callback Management

Flexible callback list management for event handling and plugin development. The Callbacks system provides a powerful way to manage lists of callbacks with configurable behavior patterns.

Capabilities

Callback List Creation

Create callback lists with configurable options to control firing behavior.

/**
 * Create a callback list with configurable options
 * @param options - Configuration string (space-separated flags)
 * @returns Callbacks object for managing callback lists
 */
$.Callbacks(options);

Configuration Options:

  • once - Callbacks can only be fired once
  • memory - Remember previous fire arguments for new callbacks
  • unique - Prevent duplicate callbacks from being added
  • stopOnFalse - Stop firing when a callback returns false

Callback Management Methods

Methods for adding, removing, and controlling callbacks.

/**
 * Add callback function(s) to the list
 * @param callbacks - One or more callback functions
 * @returns Callbacks object for chaining
 */
$.fn.add(...callbacks);

/**
 * Remove callback function(s) from the list
 * @param callbacks - One or more callback functions to remove
 * @returns Callbacks object for chaining
 */
$.fn.remove(...callbacks);

/**
 * Check if callback function exists in the list
 * @param callback - Optional specific callback to check for
 * @returns Boolean indicating presence of callback(s)
 */
$.fn.has(callback);

/**
 * Remove all callbacks from the list
 * @returns Callbacks object for chaining
 */
$.fn.empty();

Callback Firing Methods

Methods for executing callbacks with different contexts and arguments.

/**
 * Fire all callbacks with given arguments
 * @param args - Arguments to pass to callbacks
 * @returns Callbacks object for chaining
 */
$.fn.fire(...args);

/**
 * Fire all callbacks with specific context and arguments
 * @param context - Context (this) for callback execution
 * @param args - Arguments array to pass to callbacks
 * @returns Callbacks object for chaining
 */
$.fn.fireWith(context, args);

/**
 * Check if callbacks have been fired at least once
 * @returns Boolean indicating if fire() has been called
 */
$.fn.fired();

State Control Methods

Methods for controlling the state and behavior of the callback list.

/**
 * Disable the callback list (no more firing)
 * @returns Callbacks object for chaining
 */
$.fn.disable();

/**
 * Check if the callback list is disabled
 * @returns Boolean indicating disabled state
 */
$.fn.disabled();

/**
 * Lock the callback list (no more callbacks can be added)
 * @returns Callbacks object for chaining
 */
$.fn.lock();

/**
 * Check if the callback list is locked
 * @returns Boolean indicating locked state
 */
$.fn.locked();

Usage Examples

Basic Callback Management

// Create a basic callback list
const callbacks = $.Callbacks();

// Define some callback functions
function logMessage(message) {
  console.log('Log:', message);
}

function alertMessage(message) {
  alert('Alert: ' + message);
}

function processMessage(message) {
  return message.toUpperCase();
}

// Add callbacks to the list
callbacks.add(logMessage, alertMessage);

// Fire all callbacks
callbacks.fire('Hello World'); 
// Output: "Log: Hello World" and alert dialog

// Add more callbacks
callbacks.add(processMessage);

// Fire again
callbacks.fire('Another message');
// All three callbacks execute

Memory Option

// Create callback list with memory
const memoryCallbacks = $.Callbacks('memory');

// Add initial callback and fire
memoryCallbacks.add((msg) => console.log('First:', msg));
memoryCallbacks.fire('Initial message');

// Add callback later - it immediately receives the last fired arguments
memoryCallbacks.add((msg) => console.log('Second:', msg));
// Immediately outputs: "Second: Initial message"

// Fire again - both callbacks execute
memoryCallbacks.fire('New message');
// Outputs: "First: New message" and "Second: New message"

Once Option

// Create callback list that fires only once
const onceCallbacks = $.Callbacks('once');

onceCallbacks.add(
  () => console.log('First execution'),
  () => console.log('Also first execution')
);

onceCallbacks.fire(); 
// Outputs both messages

onceCallbacks.fire(); 
// No output - callbacks already fired once

// Adding new callbacks after firing has no effect with 'once'
onceCallbacks.add(() => console.log('Will not execute'));
onceCallbacks.fire(); // Still no output

Unique Option

// Create callback list that prevents duplicates
const uniqueCallbacks = $.Callbacks('unique');

function duplicateCallback() {
  console.log('This will only be added once');
}

uniqueCallbacks.add(duplicateCallback);
uniqueCallbacks.add(duplicateCallback); // Ignored due to 'unique'
uniqueCallbacks.add(duplicateCallback); // Also ignored

uniqueCallbacks.fire();
// Only executes once despite multiple add() calls

StopOnFalse Option

// Create callback list that stops when a callback returns false
const stoppableCallbacks = $.Callbacks('stopOnFalse');

stoppableCallbacks.add(
  () => { console.log('First callback'); return true; },
  () => { console.log('Second callback'); return false; },
  () => { console.log('Third callback - will not execute'); return true; }
);

stoppableCallbacks.fire();
// Outputs: "First callback" and "Second callback"
// Third callback doesn't execute because second returned false

Combined Options

// Combine multiple options
const advancedCallbacks = $.Callbacks('once memory unique stopOnFalse');

function validator1(data) {
  console.log('Validating format...');
  return data && data.length > 0;
}

function validator2(data) {
  console.log('Validating content...');
  return data && !data.includes('invalid');
}

function validator3(data) {
  console.log('This runs only if previous validators pass');
  return true;
}

// Add validators (unique prevents duplicates)
advancedCallbacks.add(validator1, validator2, validator3);
advancedCallbacks.add(validator1); // Ignored due to 'unique'

// Fire validation (once + memory + stopOnFalse)
const result = advancedCallbacks.fire('valid data');
console.log('All validators passed');

// Later callbacks added will receive memory of last fire
advancedCallbacks.add((data) => {
  console.log('Late validator received:', data);
});

Context and Arguments

// Using fireWith for specific context
const contextCallbacks = $.Callbacks();

function contextualCallback(message) {
  console.log(`${this.name} says: ${message}`);
}

contextCallbacks.add(contextualCallback);

// Fire with specific context
const speaker1 = { name: 'Alice' };
const speaker2 = { name: 'Bob' };

contextCallbacks.fireWith(speaker1, ['Hello from Alice']);
// Output: "Alice says: Hello from Alice"

contextCallbacks.fireWith(speaker2, ['Hello from Bob']);
// Output: "Bob says: Hello from Bob"

State Management

const stateCallbacks = $.Callbacks();

// Add callbacks
stateCallbacks.add(() => console.log('Callback 1'));
stateCallbacks.add(() => console.log('Callback 2'));

console.log('Has callbacks:', stateCallbacks.has()); // true
console.log('Fired:', stateCallbacks.fired()); // false
console.log('Disabled:', stateCallbacks.disabled()); // false
console.log('Locked:', stateCallbacks.locked()); // false

// Fire callbacks
stateCallbacks.fire();
console.log('Fired after fire():', stateCallbacks.fired()); // true

// Lock the list (no more adding)
stateCallbacks.lock();
console.log('Locked after lock():', stateCallbacks.locked()); // true

stateCallbacks.add(() => console.log('Will not be added')); // Ignored
stateCallbacks.fire(); // Still works

// Disable the list (no more firing)
stateCallbacks.disable();
console.log('Disabled after disable():', stateCallbacks.disabled()); // true

stateCallbacks.fire(); // Ignored - list is disabled

Practical Use Cases

Event System Implementation

// Simple event system using callbacks
function EventEmitter() {
  this.events = {};
}

EventEmitter.prototype.on = function(event, callback) {
  if (!this.events[event]) {
    this.events[event] = $.Callbacks('memory unique');
  }
  this.events[event].add(callback);
  return this;
};

EventEmitter.prototype.off = function(event, callback) {
  if (this.events[event]) {
    this.events[event].remove(callback);
  }
  return this;
};

EventEmitter.prototype.emit = function(event, ...args) {
  if (this.events[event]) {
    this.events[event].fire(...args);
  }
  return this;
};

// Usage
const emitter = new EventEmitter();
emitter.on('data', (data) => console.log('Received:', data));
emitter.emit('data', { value: 123 });

Plugin Hook System

// Plugin system with hooks
const PluginSystem = {
  hooks: {},
  
  addHook(hookName, callback, options = '') {
    if (!this.hooks[hookName]) {
      this.hooks[hookName] = $.Callbacks(options);
    }
    this.hooks[hookName].add(callback);
  },
  
  runHook(hookName, ...args) {
    if (this.hooks[hookName]) {
      return this.hooks[hookName].fire(...args);
    }
  },
  
  removeHook(hookName, callback) {
    if (this.hooks[hookName]) {
      this.hooks[hookName].remove(callback);
    }
  }
};

// Plugins can register hooks
PluginSystem.addHook('beforeSave', (data) => {
  console.log('Validating data before save');
  return data.isValid;
}, 'stopOnFalse');

PluginSystem.addHook('afterSave', (result) => {
  console.log('Data saved successfully');
});

// Application uses hooks
function saveData(data) {
  // Run pre-save hooks
  const canSave = PluginSystem.runHook('beforeSave', data);
  
  if (canSave) {
    // Simulate save
    const result = { success: true, id: Date.now() };
    
    // Run post-save hooks
    PluginSystem.runHook('afterSave', result);
    
    return result;
  }
}

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