Core Features
Master event handling in YakaJS - from simple clicks to complex custom events
Complete guide to handling user interactions and custom events with YakaJS.
.on(event, selector, handler)Attach event handlers to elements with optional event delegation.
// Simple event handler_('#button').on('click', function(e) { console.log('Button clicked!');});// Event delegation (for dynamic elements)_('#container').on('click', '.item', function(e) { console.log('Item clicked:', this);});// Multiple events_('#element').on('mouseenter mouseleave', function(e) { _(this).toggleClass('hover');});Parameters:
event (String): Event name(s), space-separatedselector (String, optional): Selector for event delegationhandler (Function): Event handler functionReturns: YakaJS object for chaining
.off(event, selector, handler)Remove event handlers.
// Remove all handlers_('#button').off('click');// Remove specific handler_('#button').off('click', myHandler);// Remove delegated handler_('#container').off('click', '.item');// Remove all events_('#element').off();.one(event, selector, handler)Attach handler that runs only once.
_('#button').one('click', function() { console.log('This will only run once!');});// With event delegation_('#container').one('click', '.item', function() { console.log('First item click only');});.click(handler)Shorthand for click events.
_('#button').click(function(e) { console.log('Clicked!');});// Trigger click_('#button').click(); // Triggers click programmatically.dblclick(handler)Double-click events.
_('#element').dblclick(function(e) { console.log('Double clicked!');});_('#element').on('mouseenter', function() { _(this).addClass('hover');});_('#element').on('mouseleave', function() { _(this).removeClass('hover');});_('#element').hover( function() { // Mouse enter _(this).addClass('hover'); }, function() { // Mouse leave _(this).removeClass('hover'); });_('#canvas').on('mousemove', function(e) { console.log('Mouse at:', e.clientX, e.clientY);});_('#element').on('contextmenu', function(e) { e.preventDefault(); // Prevent default context menu showCustomMenu(e.clientX, e.clientY);});// Key down_(document).on('keydown', function(e) { console.log('Key pressed:', e.key); if (e.key === 'Enter') { console.log('Enter pressed!'); }});// Key up_('#input').on('keyup', function(e) { console.log('Current value:', _(this).val());});// Key press_('#input').on('keypress', function(e) { console.log('Character:', e.key);});_(document).on('keydown', function(e) { // Ctrl+S if (e.ctrlKey && e.key === 's') { e.preventDefault(); saveDocument(); } // Ctrl+K (Command Palette) if (e.ctrlKey && e.key === 'k') { e.preventDefault(); _.commandPalette(); }});_('#form').on('submit', function(e) { e.preventDefault(); // Prevent form submission const data = { name: _('#name').val(), email: _('#email').val() }; console.log('Form data:', data);});// Input change_('#input').on('change', function() { console.log('New value:', _(this).val());});// Select change_('#select').on('change', function() { const selected = _(this).val(); console.log('Selected:', selected);});_('#search').on('input', function() { const query = _(this).val(); searchResults(query);});_('#input').on('focus', function() { _(this).addClass('focused');});_('#input').on('blur', function() { _(this).removeClass('focused');});_('#element').on('touchstart', function(e) { console.log('Touch started');});_('#element').on('touchmove', function(e) { console.log('Touch moving');});_('#element').on('touchend', function(e) { console.log('Touch ended');});YakaJS includes built-in swipe detection:
_('#element').swipe({ left: function() { console.log('Swiped left!'); }, right: function() { console.log('Swiped right!'); }, up: function() { console.log('Swiped up!'); }, down: function() { console.log('Swiped down!'); }, threshold: 50 // Minimum distance in pixels});_(window).on('scroll', function() { const scrollTop = _(window).scrollTop(); console.log('Scroll position:', scrollTop); if (scrollTop > 100) { _('#header').addClass('scrolled'); }});// Debounced scroll (better performance)_(window).on('scroll', _.debounce(function() { console.log('Scrolled!');}, 200));_('#scroll-button').click(function() { _('html, body').animate({ scrollTop: _('#target').offset().top }, 500);});_(window).on('resize', _.debounce(function() { console.log('Window resized:', window.innerWidth, window.innerHeight);}, 250));_(window).on('load', function() { console.log('All resources loaded!');});_(window).on('beforeunload', function(e) { e.preventDefault(); e.returnValue = 'Are you sure you want to leave?'; return 'Are you sure you want to leave?';});// Trigger custom event_('#element').trigger('myCustomEvent');// Trigger with data_('#element').trigger('myCustomEvent', { data: 'value', count: 42});// Trigger namespace event_('#element').trigger('click.myNamespace');_('#element').on('myCustomEvent', function(e, data) { console.log('Custom event triggered!', data);});// Add namespaced events_('#element').on('click.myNamespace', handler1);_('#element').on('click.myNamespace', handler2);// Remove all events in namespace_('#element').off('.myNamespace');Event delegation allows you to handle events on dynamically added elements:
// Traditional way - won't work for dynamic elements_('.item').on('click', function() { console.log('Clicked!');});// Delegation way - works for current AND future elements_('#container').on('click', '.item', function() { console.log('Clicked!', this);});Benefits:
// Multiple delegated events_('#app').on({ 'click .button': function() { console.log('Button clicked'); }, 'mouseenter .item': function() { _(this).addClass('hover'); }, 'mouseleave .item': function() { _(this).removeClass('hover'); }});The event object contains useful information:
_('#element').on('click', function(e) { e.type // Event type: 'click' e.target // Element that triggered event e.currentTarget // Element with handler attached e.preventDefault() // Prevent default action e.stopPropagation() // Stop event bubbling // Mouse position e.clientX, e.clientY // Relative to viewport e.pageX, e.pageY // Relative to document e.screenX, e.screenY // Relative to screen // Keyboard modifiers e.ctrlKey // Ctrl key pressed e.shiftKey // Shift key pressed e.altKey // Alt key pressed e.metaKey // Meta/Command key pressed // Keyboard e.key // Key value: 'Enter', 'a', etc. e.code // Physical key code: 'KeyA', 'Enter' e.keyCode // Numeric key code (deprecated) // Mouse buttons e.button // 0: left, 1: middle, 2: right e.buttons // Bitmask of pressed buttons});Execute handler only after events stop firing for a specified time:
// Search as user types (with delay)_('#search').on('input', _.debounce(function() { const query = _(this).val(); performSearch(query);}, 300)); // Wait 300ms after user stops typingExecute handler at most once per specified time period:
// Scroll handler that runs max once per 100ms_(window).on('scroll', _.throttle(function() { updateScrollPosition();}, 100));Always remove event handlers when elements are removed to prevent memory leaks:
// Store reference to handlerfunction myHandler(e) { console.log('Clicked!');}// Add handler_('#element').on('click', myHandler);// Later: remove handler_('#element').off('click', myHandler);// Or remove all handlers before removing element_('#element').off().remove();// GOOD: Single handler for all items_('#container').on('click', '.item', function() { console.log('Item clicked');});// BAD: Handler for each item_('.item').each(function() { _(this).on('click', function() { console.log('Item clicked'); });});_('#toggle').click(function() { _('#menu').toggle(); _(this).toggleClass('active');});_('#delete').click(function(e) { if (!confirm('Are you sure?')) { e.preventDefault(); return false; } // Proceed with deletion});_('#form').one('submit', function(e) { e.preventDefault(); _(this).find('button[type="submit"]') .prop('disabled', true) .text('Submitting...'); // Submit form data submitFormData();});// Close menu when clicking outside_(document).on('click', function(e) { if (!_(e.target).closest('#menu').length) { _('#menu').hide(); }});_(document).on('keydown', function(e) { if (e.key === 'Escape') { _('#modal').hide(); _('#menu').hide(); }});Use event delegation for dynamic content:
_('#container').on('click', '.item', handler);Debounce expensive operations:
_(window).on('resize', _.debounce(handler, 250));Clean up event handlers:
_('#element').off().remove();Prevent default when needed:
_('a').on('click', function(e) { e.preventDefault();});Use namespaces for plugin events:
_('#element').on('click.myPlugin', handler);Cache event target lookups:
_('#container').on('click', '.item', function(e) { const $item = _(this); // Cache reference $item.addClass('active'); $item.find('.icon').show();});